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/logs/.gitkeep
|
||||
/app/phpunit.xml
|
||||
/bin/
|
||||
/build/
|
||||
/composer.phar
|
||||
/var/*
|
||||
|
@ -37,13 +38,3 @@ output.xml
|
|||
log.html
|
||||
report.html
|
||||
__pycache__
|
||||
|
||||
### Debian packaging
|
||||
debian/ogdhcp
|
||||
debian/*.substvars
|
||||
debian/*.log
|
||||
debian/.debhelper/
|
||||
debian/files
|
||||
debian/*.debhelper
|
||||
debian/*.debhelper.log
|
||||
debian/debhelper-build-stamp
|
||||
|
|
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.
|
||||
|
40
CHANGELOG.md
40
CHANGELOG.md
|
@ -1,40 +0,0 @@
|
|||
# Changelog
|
||||
|
||||
## [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,112 +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('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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
notifyBuildStatus('narenas@qindel.com')
|
||||
}
|
||||
}
|
||||
}
|
||||
// stage ('Publish to Debian Repository') {
|
||||
// agent { label 'debian-repo' }
|
||||
// steps {
|
||||
// sh "aptly repo add opengnsys-devel /var/tmp/opengnsys/debian-repo/*.deb"
|
||||
// }
|
||||
// }
|
||||
|
|
@ -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
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine", "!console"]
|
||||
syslog:
|
||||
type: syslog
|
||||
ident: "ogdhcp"
|
||||
level: info
|
||||
channels: ["!event"]
|
||||
|
||||
when@test:
|
||||
monolog:
|
|
@ -4,7 +4,7 @@
|
|||
# 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
|
||||
parameters:
|
||||
backup_dir: '%kernel.project_dir%/../etc/kea/backup'
|
||||
backup_dir: '%kernel.project_dir%/etc/kea/backup'
|
||||
services:
|
||||
# default configuration for services in *this* file
|
||||
_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,129 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
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"
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
echo "Configurando ogdhcp..."
|
||||
|
||||
# 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..."
|
||||
PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
|
||||
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"
|
||||
if [ -e "$KEA_CONFIG" ]; then
|
||||
dpkg-divert --package ogdhcp --divert "$KEA_CONFIG.dpkg-dist" --rename "$KEA_CONFIG"
|
||||
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
|
||||
fi
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
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
|
||||
systemctl restart kea-dhcp4-server
|
||||
systemctl restart kea-ctrl-agent
|
||||
systemctl restart php$PHP_VERSION-fpm
|
||||
|
||||
exit 0
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Asegurarse de que el usuario exista
|
||||
USER="opengnsys"
|
||||
HOME_DIR="/opt/opengnsys"
|
||||
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
|
||||
|
||||
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.
|
||||
WORKDIR=/tmp/ogdhcp_installer
|
||||
INSTALL_TARGET=$(jq -r '.ogDhcp_Dir' "$CONFIG_FILE")
|
||||
SYMFONY_TARGET=$INSTALL_TARGET/api
|
||||
PATH=$PATH:$INSTALL_TARGET/bin
|
||||
|
||||
if command -v service &>/dev/null; then
|
||||
|
@ -58,7 +57,7 @@ function globalSetup() {
|
|||
SOCKET_PATH="/run/php/php__PHPVERSION__-fpm-ogdhcp.sock"
|
||||
|
||||
# Registro de incidencias.
|
||||
OGLOGFILE="$SYMFONY_TARGET/var/log/${PROGRAMNAME%.sh}.log"
|
||||
OGLOGFILE="$INSTALL_TARGET/var/log/${PROGRAMNAME%.sh}.log"
|
||||
LOG_FILE="/tmp/$(basename "$OGLOGFILE")"
|
||||
}
|
||||
|
||||
|
@ -139,26 +138,37 @@ function createDirs() {
|
|||
fi
|
||||
|
||||
local path_opengnsys_base="$1"
|
||||
local symfony_target="$path_opengnsys_base/api"
|
||||
|
||||
# Crear estructura de directorios.
|
||||
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"/etc/kea/backup
|
||||
mkdir -p "$path_opengnsys_base"/{bin,config,docs,public,src,etc/kea/backup,templates,var/{cache,log},vendor}
|
||||
if [ $? -ne 0 ]; then
|
||||
errorAndLog "${FUNCNAME}(): error while creating dirs. Do you have write permissions?"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Mover el fichero de registro de instalación al directorio de logs.
|
||||
echoAndLog "${FUNCNAME}(): moving installation log file"
|
||||
mv "$LOG_FILE" "$symfony_target/var/log" && LOG_FILE="$OGLOGFILE"
|
||||
usermod -aG $OPENGNSYS_CLIENT_USER _kea
|
||||
|
||||
# Crear usuario ficticio.
|
||||
if id -u "$OPENGNSYS_CLIENT_USER" &>/dev/null; then
|
||||
echoAndLog "${FUNCNAME}(): user \"$OPENGNSYS_CLIENT_USER\" is already created"
|
||||
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.
|
||||
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"
|
||||
return 0
|
||||
|
@ -171,39 +181,16 @@ function createDirs() {
|
|||
|
||||
function create_ogdhcp_project {
|
||||
# Crea el usuario ogdhcp si no existe
|
||||
echo "Creating ogdhcp user..."
|
||||
local path_opengnsys_base="$1"
|
||||
local symfony_target="$path_opengnsys_base/api"
|
||||
echo $symfony_target
|
||||
# Verificar si el usuario OPENGNSYS_CLIENT_USER existe
|
||||
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 ! id -u opengnsys &>/dev/null; then
|
||||
echoAndLog "${FUNCNAME}(): creating opengnsys user"
|
||||
useradd opengnsys 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
errorAndLog "${FUNCNAME[0]}(): error creating user \"$OPENGNSYS_CLIENT_USER\""
|
||||
errorAndLog "${FUNCNAME}(): error creating opengnsys user"
|
||||
return 1
|
||||
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
|
||||
echoAndLog "${FUNCNAME}(): creating directory $path_opengnsys_base with opengnsys user"
|
||||
sudo mkdir -p "$path_opengnsys_base"
|
||||
|
@ -223,17 +210,16 @@ function copyServerFiles() {
|
|||
fi
|
||||
|
||||
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.
|
||||
local SOURCES=(
|
||||
config
|
||||
#public
|
||||
src
|
||||
etc
|
||||
.env
|
||||
bin
|
||||
composer.json
|
||||
composer.lock
|
||||
phpunit.xml.dist
|
||||
symfony.lock
|
||||
)
|
||||
|
@ -241,9 +227,10 @@ function copyServerFiles() {
|
|||
config
|
||||
#public
|
||||
src
|
||||
etc
|
||||
.env
|
||||
bin
|
||||
composer.json
|
||||
composer.lock
|
||||
phpunit.xml.dist
|
||||
symfony.lock
|
||||
)
|
||||
|
@ -256,27 +243,19 @@ function copyServerFiles() {
|
|||
# Copiar ficheros.
|
||||
echoAndLog "${FUNCNAME}(): copying files to server directories"
|
||||
|
||||
pushd "$WORKDIR/ogdhcp/api" || return
|
||||
pushd "$WORKDIR/ogdhcp" || return
|
||||
local i
|
||||
for (( i = 0; i < ${#SOURCES[@]}; i++ )); do
|
||||
if [ -f "${SOURCES[$i]}" ]; then
|
||||
echoAndLog "Copying ${SOURCES[$i]} to $symfony_target/${TARGETS[$i]}"
|
||||
cp -a "${SOURCES[$i]}" "$symfony_target/${TARGETS[$i]}"
|
||||
echoAndLog "Copying ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}"
|
||||
cp -a "${SOURCES[$i]}" "$path_opengnsys_base/${TARGETS[$i]}"
|
||||
elif [ -d "${SOURCES[$i]}" ]; then
|
||||
echoAndLog "Copying content of ${SOURCES[$i]} to $symfony_target/${TARGETS[$i]}"
|
||||
cp -a "${SOURCES[$i]}"/* "$symfony_target/${TARGETS[$i]}"
|
||||
echoAndLog "Copying content of ${SOURCES[$i]} to $path_opengnsys_base/${TARGETS[$i]}"
|
||||
cp -a "${SOURCES[$i]}"/* "$path_opengnsys_base/${TARGETS[$i]}"
|
||||
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
|
||||
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"
|
||||
chown -R "$OPENGNSYS_CLIENT_USER:$OPENGNSYS_CLIENT_USER" "$INSTALL_TARGET"
|
||||
|
||||
|
@ -287,8 +266,7 @@ function copyServerFiles() {
|
|||
function runComposer() {
|
||||
echoAndLog "Running composer.phar to install dependencies..."
|
||||
local path_opengnsys_base="$1"
|
||||
local symfony_target="$path_opengnsys_base/api"
|
||||
pushd $symfony_target
|
||||
pushd $path_opengnsys_base
|
||||
pwd
|
||||
# Ejecutar composer.phar
|
||||
sudo -u "$OPENGNSYS_CLIENT_USER" composer --no-interaction install
|
||||
|
@ -396,8 +374,7 @@ add_write_permission_apparmor() {
|
|||
# Función para configurar Nginx
|
||||
setup_nginx() {
|
||||
local path_opengnsys_base="$1"
|
||||
local symfony_target="$path_opengnsys_base/api"
|
||||
local public_dir="$symfony_target/public"
|
||||
local public_dir="$path_opengnsys_base/public"
|
||||
#ip_address_server=$(get_ip_address "$DEFAULTDEV")
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "Error: El archivo de configuración no se encontró."
|
||||
|
@ -604,18 +581,6 @@ if [ "$(whoami)" != 'root' ]; then
|
|||
exit 1
|
||||
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
|
||||
|
||||
echoAndLog "OpenGnsys installation begins at $(date)"
|
||||
|
@ -625,7 +590,6 @@ pushd $WORKDIR
|
|||
|
||||
checkDependencies
|
||||
# Si es necesario, descarga el repositorio de código en directorio temporal
|
||||
|
||||
if [ $REMOTE -eq 1 ]; then
|
||||
downloadCode $GIT_REPO
|
||||
if [ $? -ne 0 ]; then
|
||||
|
@ -636,7 +600,6 @@ else
|
|||
ln -fs "$(dirname $PROGRAMDIR)" ogdhcp
|
||||
fi
|
||||
|
||||
|
||||
create_ogdhcp_project ${INSTALL_TARGET}
|
||||
if [ $? -ne 0 ]; then
|
||||
errorAndLog "Error while creating skeleton directory!"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -82,7 +82,7 @@ class CurlKeaService
|
|||
$config_text = json_encode($get_output[0]['arguments']);
|
||||
$configurationParsed = str_replace('\\', '', $config_text);
|
||||
|
||||
$backup_dir = __DIR__ . '/../../../../etc/kea/backup';
|
||||
$backup_dir = __DIR__ . '/../../../etc/kea/backup';
|
||||
if (!is_dir($backup_dir)) {
|
||||
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