Compare commits

..

47 Commits

Author SHA1 Message Date
Nicolas Arenas c172ba0682 Remove extra chareacters at the beginning of the line
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 17:42:40 +02:00
Nicolas Arenas 088b33a235 Fix problem with ip space at the end
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 17:39:16 +02:00
Luis Gerardo Romero Garcia 3496a993c9 refs #799 adds daemon reload
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 17:26:35 +02:00
Nicolas Arenas 36a1a8cc33 Fix env var
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 17:25:01 +02:00
Luis Gerardo Romero Garcia d53fddf3a9 refs #799 removes kea password comprobation in kea agent service
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 17:15:18 +02:00
Nicolas Arenas bd88f58303 Update url to check api up
testing/og-dhcp-API/pipeline/head Build queued... Details
2024-10-01 17:08:21 +02:00
Luis Gerardo Romero Garcia 78639f92a3 refs #799 fix a error in adding apparmor write permissions to kea conf
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 16:41:49 +02:00
Luis Gerardo Romero Garcia aa1b85a785 refs #799 fix a error in the comment kea ctrl authentication and a typo in the swagger doc 2024-10-01 16:41:49 +02:00
Nicolas Arenas dbf5c9ebc0 Fix get email
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 16:21:30 +02:00
Luis Gerardo Romero Garcia c136f004e9 refs #799 adds apparmor exception to write in kea conf and delete hash in controller
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 16:04:40 +02:00
Luis Gerardo Romero Garcia 4266bdffb4 refs #799 adds apparmor exception to write in kea conf 2024-10-01 16:04:40 +02:00
Nicolas Arenas 35c44c163f Improve plugin installation
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 14:12:34 +02:00
Nicolas Arenas 231cbe92d8 Change script to get user email
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 13:58:58 +02:00
Nicolas Arenas c9764a99d3 Revert commit as it was working fine 2024-10-01 13:37:53 +02:00
Nicolas Arenas 529f4a3653 Test api in proper stage
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 13:34:17 +02:00
Nicolas Arenas a6968ca83a Move vagrant destroy server to post action 2024-10-01 13:32:31 +02:00
Nicolas Arenas 139102eec8 Update Jenkinsfile with copilot help
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 13:27:31 +02:00
Luis Gerardo Romero Garcia 14a2ae7d4f refs #799 fix conflict
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 13:07:13 +02:00
Qindel e1f498c3df refs #799 fix problems with composer routes 2024-10-01 13:07:13 +02:00
Nicolas Arenas 9a3c5bd80f Fix typo
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 12:37:11 +02:00
Nicolas Arenas 57e01f880b Using mailer plugin
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 12:24:35 +02:00
Nicolas Arenas 5617453e0e Deshabilita las ejecuciones concurrentes
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 12:11:17 +02:00
Nicolas Arenas 110f7e3370 Add mail notification to Jenkinsfile
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 12:08:05 +02:00
Nicolas Arenas 458930c7cb Update vagrant and Jenkins for new installer
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 11:17:01 +02:00
Luis Gerardo Romero Garcia 2c4160e629 refs #799 fix composer error and deletes download composer.phar function
testing/og-dhcp-API/pipeline/head This commit looks good Details
2024-10-01 11:05:42 +02:00
Luis Gerardo Romero Garcia d844185d89 refs #799 adds nginx installation function, configure php-fpm based on php version installed, adds comments in kea agent and adds nginx template 2024-10-01 11:05:42 +02:00
Luis Gerardo Romero Garcia 6b79e04805 refs #799 deletes a lot of innecesaries files 2024-10-01 11:05:35 +02:00
Qindel bfb040fbaf refs #797 removes schema swagger for errors with nelmio, adds nelmio to composer.json 2024-10-01 11:02:27 +02:00
Nicolas Arenas 8f633961bb Update some typos
testing/og-dhcp-API/pipeline/head This commit looks good Details
2024-10-01 09:46:56 +02:00
Nicolas Arenas 62134cd7fd Update provision and swagger init file
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 09:28:16 +02:00
Nicolas Arenas 8e2f093da1 Replace echo command and get the ip
testing/og-dhcp-API/pipeline/head This commit looks good Details
2024-10-01 08:51:22 +02:00
Nicolas Arenas 6973eb7d67 Update password for user qindel
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 08:14:15 +02:00
Nicolas Arenas 1f0561666c Fix wrong directory in vagrantfile
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 00:58:06 +02:00
Nicolas Arenas 90e3a9ef32 Updating scripts to get environment ready
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 00:49:47 +02:00
Nicolas Arenas 35c2ec682e Update apache config
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-10-01 00:13:37 +02:00
Nicolas Arenas 58a670d3f2 Not destroying server to check installation
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-09-30 19:47:19 +02:00
Nicolas Arenas e419c3bc18 Force vagrant provision
testing/og-dhcp-API/pipeline/head This commit looks good Details
2024-09-30 19:38:14 +02:00
Nicolas Arenas 8eba47c2e0 Fix typo
testing/og-dhcp-API/pipeline/head This commit looks good Details
2024-09-30 19:33:10 +02:00
Nicolas Arenas d6587e5209 Updated sync method for deployment
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-09-30 19:29:58 +02:00
Nicolas Arenas 215da35234 Launch provision in installer
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-09-30 19:26:45 +02:00
Nicolas Arenas 9c106f04c0 Update PATH
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-09-30 19:09:25 +02:00
Nicolas Arenas 9935af4f48 Update PATH environment var
testing/og-dhcp-API/pipeline/head Something is wrong with the build of this commit Details
2024-09-30 19:04:54 +02:00
Nicolas Arenas 1fb3b305e6 Install plugin for esxi and specify provider
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-09-30 18:35:11 +02:00
Nicolas Arenas 1659275b19 Updated Jenkinsfile
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-09-30 18:32:05 +02:00
Nicolas Arenas 17f0768f6f Update Jenkinsfile and Vagrantfile to create environment
testing/og-dhcp-API/pipeline/head There was a failure building this commit Details
2024-09-30 18:29:18 +02:00
Nicolas Arenas 31c0976e42 Test Jenkins agent
testing/og-dhcp-API/pipeline/head Something is wrong with the build of this commit Details
2024-09-30 14:16:19 +02:00
Nicolas Arenas 114a1de095 skelton pipeline 2024-09-30 13:26:49 +02:00
67 changed files with 1451 additions and 3404 deletions

View File

18
.gitignore vendored
View File

@ -5,6 +5,7 @@
!app/cache/.gitkeep
!app/logs/.gitkeep
/app/phpunit.xml
/bin/
/build/
/composer.phar
/var/*
@ -30,20 +31,3 @@
.phpunit.result.cache
/phpunit.xml
###< symfony/phpunit-bridge ###
.venv
ogdhcp.code-workspace
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

View File

@ -1,43 +0,0 @@
# CHANGELOG
# [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.

View File

@ -1,32 +0,0 @@
# Changelog
## [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.

View File

@ -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"
// }
// }

View File

@ -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);
};

View File

@ -1,48 +0,0 @@
nelmio_api_doc:
documentation:
info:
title: OgDHCP API
description: OgDHCP API documentation
version: 1.0.0
components:
schemas:
Host:
type: object
properties:
hostname:
type: string
description: The hostname of the device
example: "pc11"
hw-address:
type: string
description: The hardware address (MAC)
example: "56:6f:c7:4f:00:4f"
ip-address:
type: string
description: The IP address assigned to the host
example: "192.168.5.11"
Subnet:
type: object
properties:
id:
type: integer
description: The ID of the subnet
subnet:
type: string
description: The name of the subnet
next-server:
type: string
description: The next server in the subnet
boot-file-name:
type: string
description: The boot file name for the subnet
reservations:
type: array
items:
$ref: '#/components/schemas/Host'
description: The reservations in the subnet
areas: # to filter documented areas
path_patterns:
- ^/ogdhcp/ # Accepts routes under /api except /api/doc

View File

@ -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']);
};

File diff suppressed because it is too large Load Diff

View File

View File

@ -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"
}
}

View File

@ -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:

View File

@ -0,0 +1,9 @@
nelmio_api_doc:
documentation:
info:
title: My App
description: This is an awesome app!
version: 1.0.0
areas: # to filter documented areas
path_patterns:
- ^/ogdhcp/ # Accepts routes under /api except /api/doc

View File

@ -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'
services:
# default configuration for services in *this* file
_defaults:

6
debian/README vendored
View File

@ -1,6 +0,0 @@
The Debian Package ogdhcp
----------------------------
<Comments regarding the Package.>
-- vagrant <vagrant@build> Wed, 05 Mar 2025 19:49:47 +0000

View File

@ -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

10
debian/README.source vendored
View File

@ -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

14
debian/changelog vendored
View File

@ -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

38
debian/control vendored
View File

@ -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.>

43
debian/copyright vendored
View File

@ -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/

11
debian/ogdhcp.config vendored
View File

@ -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

16
debian/ogdhcp.dirs vendored
View File

@ -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

View File

@ -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/

129
debian/ogdhcp.postinst vendored
View File

@ -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

15
debian/ogdhcp.preinst vendored
View File

@ -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

69
debian/ogdhcp.prerm vendored
View File

@ -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

View File

@ -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

28
debian/rules vendored
View File

@ -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;

View File

@ -1 +0,0 @@
3.0 (native)

View File

@ -1,9 +1,9 @@
server {
listen 8081;
listen 80;
server_name __SERVERIP__ localhost; # IP del servidor
# Raíz del documento para el proyecto Symfony
root __PUBLICDIR__;
root /opt/ogdhcp/public;
# Bloque para manejar las solicitudes a /ogdhcp
location /ogdhcp {
@ -18,7 +18,7 @@ server {
# Bloque para manejar las solicitudes a index.php
location ~ ^/index.php(/|$) {
include fastcgi_params;
fastcgi_pass unix:/run/php/php__PHPVERSION__-fpm-ogdhcp.sock;
fastcgi_pass unix:/run/php/php__PHPVERSION__-fpm-ogdhcp.sock; # Asegúrate de que esto sea correcto
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;

View File

@ -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

View File

@ -1,4 +0,0 @@
[Unit]
# Eliminamos la condición de existencia del archivo de contraseña
ConditionFileNotEmpty=

View File

@ -1,7 +0,0 @@
{
"interfaces": ["eth0", "eth1"],
"ogbootIP": "172.17.8.37",
"ogDhcpIP": "172.17.8.37",
"ogDhcp_Dir": "/opt/opengnsys/ogdhcp"
}

View File

@ -10,13 +10,7 @@ function globalSetup() {
current_dir=$(dirname "$0")
PROGRAMDIR=$(readlink -e "$current_dir")
PROGRAMNAME=$(basename "$0")
OPENGNSYS_CLIENT_USER="opengnsys"
current_dir=$(dirname "$0")
PROGRAMDIR=$(readlink -e "$current_dir")
# Ruta del archivo config_ogdhcp.json proporcionado por el usuario
CONFIG_FILE="$PROGRAMDIR/config_ogdhcp.json"
OPENGNSYS_CLIENT_USER="ogdhcp"
# Comprobar si se ha descargado el paquete comprimido (REMOTE=0) o sólo el instalador (REMOTE=1).
if [ -d "$PROGRAMDIR/../installer" ]; then
@ -33,8 +27,7 @@ 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
INSTALL_TARGET=/opt/ogdhcp
PATH=$PATH:$INSTALL_TARGET/bin
if command -v service &>/dev/null; then
@ -58,7 +51,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")"
}
@ -92,18 +85,17 @@ function checkDependencies() {
)
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
# Comprobar cada dependencia
for dep in "${DEPENDENCIES[@]}"; do
if ! dpkg -s "$dep" >/dev/null 2>&1; then
echoAndLog "$dep is not installed. Installing..."
apt-get install -y --no-install-recommends "$dep"
sudo apt-get install -y --no-install-recommends "$dep"
else
echoAndLog "$dep is already installed."
fi
done
sed -i '/ConditionFileNotEmpty=\/etc\/kea\/kea-api-password/d' /usr/lib/systemd/system/kea-ctrl-agent.service
chown -R _kea:_kea /etc/kea
systemctl daemon-reload
systemctl restart kea-ctrl-agent.service
echoAndLog "Dependencies checked."
@ -139,26 +131,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
@ -166,54 +169,34 @@ function createDirs() {
# Cambiar permisos de usuario
echoAndLog "Changing user permission"
chown -R "$OPENGNSYS_CLIENT_USER:$OPENGNSYS_CLIENT_USER" "$INSTALL_TARGET"
# Copiar .env
cp -a "$WORKDIR/ogdhcp/.env" "${path_opengnsys_base}/.env"
}
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 ogdhcp &>/dev/null; then
echoAndLog "${FUNCNAME}(): creating ogdhcp user"
useradd ogdhcp 2>/dev/null
if [ $? -ne 0 ]; then
errorAndLog "${FUNCNAME[0]}(): error creating user \"$OPENGNSYS_CLIENT_USER\""
errorAndLog "${FUNCNAME}(): error creating ogdhcp 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"
# Crea el directorio path_opengnsys_base con el usuario ogdhcp
echoAndLog "${FUNCNAME}(): creating directory $path_opengnsys_base with ogdhcp user"
sudo mkdir -p "$path_opengnsys_base"
sudo chown opengnsys:opengnsys $path_opengnsys_base
sudo chown ogdhcp:ogdhcp $path_opengnsys_base
if [ $? -ne 0 ]; then
errorAndLog "${FUNCNAME}(): error while creating directory $path_opengnsys_base"
return 1
fi
echoAndLog "Directory $path_opengnsys_base created with opengnsys user"
echoAndLog "Directory $path_opengnsys_base created with ogdhcp user"
}
function copyServerFiles() {
@ -223,17 +206,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 +223,10 @@ function copyServerFiles() {
config
#public
src
etc
.env
bin
composer.json
composer.lock
phpunit.xml.dist
symfony.lock
)
@ -256,27 +239,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 +262,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
@ -395,21 +369,14 @@ 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"
#ip_address_server=$(get_ip_address "$DEFAULTDEV")
if [[ ! -f "$CONFIG_FILE" ]]; then
echo "Error: El archivo de configuración no se encontró."
get_first_network_interface_with_traffic
if [[ -z "$DEFAULTDEV" ]]; then
echo "Error: No se encontró una interfaz de red activa."
exit 1
fi
ip_address_server=$(jq -r '.ogDhcpIP' "$CONFIG_FILE")
if [[ -z "$ip_address_server" ]]; then
echo "Error: No se pudo obtener la dirección IP del servidor desde el archivo de configuración."
exit 1
fi
ip_address_server=$(get_ip_address "$DEFAULTDEV")
php_version=$(get_php_fpm_version)
if [[ -z "$php_version" ]]; then
@ -422,11 +389,10 @@ setup_nginx() {
echo "Error: La plantilla de Nginx no se encontró."
exit 1
fi
nginx_content=$(<"$NGINX_TEMPLATE")
nginx_content="${nginx_content//__SERVERIP__/$ip_address_server}"
nginx_content="${nginx_content//__PHPVERSION__/$php_version}"
nginx_content="${nginx_content//__PUBLICDIR__/$public_dir}"
# Crear el archivo de configuración de Nginx
echo "$nginx_content" > "$NGINX_OUTPUT"
@ -436,9 +402,9 @@ setup_nginx() {
ln -sf "$NGINX_OUTPUT" /etc/nginx/sites-enabled/ogdhcp.conf
echo "Enlace simbólico creado en /etc/nginx/sites-enabled/ogdhcp.conf."
# Modificar nginx.conf para ejecutar como opengnsys
sed -i 's/user www-data;/user opengnsys;/g' "$NGINX_CONF_PATH"
echo "Nginx configurado para ejecutarse como opengnsys."
# Modificar nginx.conf para ejecutar como ogdhcp
sed -i 's/user www-data;/user ogdhcp;/g' "$NGINX_CONF_PATH"
echo "Nginx configurado para ejecutarse como ogdhcp."
# Reiniciar Nginx
systemctl restart nginx.service
@ -458,22 +424,16 @@ modify_php_fpm_config() {
new_fpm_conf_path="/etc/php/$php_version/fpm/pool.d/ogdhcp.conf"
socket_path="/run/php/php$php_version-fpm-ogdhcp.sock"
# Verificar si el archivo new_fpm_conf_path ya existe
if [[ -f "$new_fpm_conf_path" ]]; then
echo "El archivo $new_fpm_conf_path ya existe. No se realizarán modificaciones."
return
fi
# Copiar el archivo www.conf a opengnsys.conf
# Copiar el archivo www.conf a ogdhcp.conf
cp "$php_fpm_conf_path" "$new_fpm_conf_path"
# Modificar el archivo ogdhcp.conf
sed -i 's/\[www\]/[ogdhcp]/g' "$new_fpm_conf_path"
sed -i 's/user = www-data/user = opengnsys/g' "$new_fpm_conf_path"
sed -i 's/group = www-data/group = opengnsys/g' "$new_fpm_conf_path"
sed -i 's/user = www-data/user = ogdhcp/g' "$new_fpm_conf_path"
sed -i 's/group = www-data/group = ogdhcp/g' "$new_fpm_conf_path"
sed -i "s|listen =.*|listen = $socket_path|g" "$new_fpm_conf_path"
sed -i 's/listen.owner = www-data/listen.owner = opengnsys/g' "$new_fpm_conf_path"
sed -i 's/listen.group = www-data/listen.group = opengnsys/g' "$new_fpm_conf_path"
sed -i 's/listen.owner = www-data/listen.owner = ogdhcp/g' "$new_fpm_conf_path"
sed -i 's/listen.group = www-data/listen.group = ogdhcp/g' "$new_fpm_conf_path"
# Reiniciar PHP-FPM
systemctl restart php"$php_version"-fpm.service
@ -489,82 +449,6 @@ modify_php_fpm_config() {
}
configure_kea() {
# Verificar si jq está instalado
if ! command -v jq &> /dev/null; then
echo "jq no está instalado. Por favor, instala jq para continuar."
exit 1
fi
# Verificar si el archivo de configuración existe
if [ ! -f "$CONFIG_FILE" ]; then
echo "El archivo $CONFIG_FILE no se encuentra. Asegúrate de que esté disponible antes de la instalación."
exit 1
fi
# Leer los parámetros del archivo JSON usando jq
INTERFACES=$(jq -r '.interfaces[]' "$CONFIG_FILE")
OGBOOT_IP=$(jq -r '.ogbootIP' "$CONFIG_FILE")
# Crear la configuración mínima de Kea DHCP
KEA_CONFIG="/etc/kea/kea-dhcp4.conf"
# Hacer una copia de seguridad del archivo kea-dhcp4.conf si ya existe
if [ -f "$KEA_CONFIG" ]; then
cp "$KEA_CONFIG" "$KEA_CONFIG.backup"
echo "Se ha creado una copia de seguridad del archivo de configuración actual en $KEA_CONFIG.backup"
fi
# Generar la configuración mínima para Kea DHCP
cat > "$KEA_CONFIG" << EOL
{
"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"
}
}
}
EOL
echo "Se ha generado la configuración mínima de Kea DHCP en $KEA_CONFIG"
# Reiniciar el servicio de Kea DHCP y verificar si se reinicia correctamente
echo "Reiniciando el servicio Kea DHCP..."
sudo systemctl restart kea-dhcp4-server.service
# Comprobar el estado del servicio Kea DHCP
if systemctl is-active --quiet kea-dhcp4-server.service; then
echo "Kea DHCP reiniciado correctamente."
else
echo "Error al reiniciar Kea DHCP."
exit 1
fi
}
#####################################################################
####### Algunas funciones útiles de propósito general:
#####################################################################
@ -604,18 +488,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 +497,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 +507,6 @@ else
ln -fs "$(dirname $PROGRAMDIR)" ogdhcp
fi
create_ogdhcp_project ${INSTALL_TARGET}
if [ $? -ne 0 ]; then
errorAndLog "Error while creating skeleton directory!"
@ -684,13 +554,6 @@ if [ $? -ne 0 ]; then
exit 1
fi
configure_kea
if [ $? -ne 0 ]; then
errorAndLog "Error configuring Kea DHCP initial configuration"
exit 1
fi
# install_kea
# install_php
# install_composer

View File

@ -1,25 +0,0 @@
#!/bin/bash
set -x
URL_REPO="https://ognproject.evlt.uma.es/gitea/opengnsys/ogdhcp.git"
BRANCH=${OGDHCP_BRANCH:-"main"}
DOWNLOADDIR=${OGDHCP_DOWNLOADDIR:-"/tmp/ogdhcp"}
apt install -y git vim
git config --global http.sslVerify false
git clone -b $BRANCH $URL_REPO $DOWNLOADDIR
cd $DOWNLOADDIR/installer
ogBoot_ServerIP=${1:-"172.17.8.82"}
ogDhcp_ServerIP=${2:-"172.17.8.37"}
ogDhcp_Dir=${3:-"/opt/opengnsys/ogdhcp"}
cat > config_ogdhcp.json <<EOF
{
"interfaces": ["eth0", "eth1"],
"ogbootIP": "$ogBoot_ServerIP",
"ogDhcpIP": "$ogDhcp_ServerIP",
"ogDhcp_Dir": "$ogDhcp_Dir"
}
EOF
chmod 755 ogdhcp_installer.sh
./ogdhcp_installer.sh

View File

@ -0,0 +1,986 @@
<?php
// src/DhcpBundle/Controller/DhcpController.php
namespace App\DhcpBundle\Controller;
use OpenApi\Annotations as OA;
use Psr\Log\LoggerInterface;
use App\DhcpBundle\Service\CurlKeaService;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Exception;
class DhcpController
{
private $logger;
/**
* @OA\Info(title="Ogdhcp API", version="1.0")
*/
/**
* @OA\Schema(
* schema="Subnet",
* type="object",
* @OA\Property(property="id", type="integer", description="The ID of the subnet"),
* @OA\Property(property="subnet", type="string", description="The name of the subnet"),
* @OA\Property(property="next-server", type="string", description="The next server in the subnet"),
* @OA\Property(property="boot-file-name", type="string", description="The boot file name for the subnet"),
* @OA\Property(
* property="reservations",
* type="array",
* @OA\Items(type="object", description="The reservations in the subnet")
* )
* )
*/
private $curlKeaService;
public function __construct(CurlKeaService $curlKeaService, LoggerInterface $logger)
{
$this->curlKeaService = $curlKeaService;
$this->logger = $logger;
}
/**
* @Route("/ogdhcp/v1/status", name="getDhcpStatus", methods={"GET"})
* @OA\Get(
* path="/ogdhcp/v1/status",
* summary="Get ogDHCP status",
* @OA\Response(
* response=200,
* description="Status retrieved successfully",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="disk_usage", type="object",
* @OA\Property(property="total", type="string"),
* @OA\Property(property="used", type="string"),
* @OA\Property(property="available", type="string"),
* @OA\Property(property="percentage", type="string")
* ),
* @OA\Property(property="default_oglive", type="string"),
* @OA\Property(property="installed_oglives", type="array", @OA\Items(type="string")),
* @OA\Property(property="services_status", type="object",
* @OA\Property(property="dhcp_daemon", type="string"),
* @OA\Property(property="nginx", type="string"),
* @OA\Property(property="tftpboot", type="string")
* )
* )
* )
* )
*/
public function getDhcpStatus(): Response
{
// Obtener el uso de disco
$diskUsageResult = $this->getDiskUsage();
if (!$diskUsageResult) {
return new JsonResponse(['error' => 'Failed to retrieve disk usage'], Response::HTTP_INTERNAL_SERVER_ERROR);
}
// Obtener el estado de los servicios de ogDHCP (similar a check_services_status en ogboot)
$servicesStatusResult = $this->getServicesStatus();
if (!$servicesStatusResult) {
return new JsonResponse(['error' => 'Failed to retrieve services status'], Response::HTTP_INTERNAL_SERVER_ERROR);
}
// Obtener las subredes y las reservas asociadas
$subnetsResult = $this->getSubnetsService();
if (!$subnetsResult) {
return new JsonResponse(['error' => 'Failed to retrieve subnets'], Response::HTTP_INTERNAL_SERVER_ERROR);
}
// Componer la respuesta
$response = [
'disk_usage' => $diskUsageResult,
'subnets' => $subnetsResult,
'services_status' => $servicesStatusResult
];
return new JsonResponse($response, Response::HTTP_OK);
}
private function getDiskUsage(): array
{
// Simular la salida del comando df para obtener el uso del disco
$output = shell_exec("df -h /opt/ogdhcp | tail -1 | awk '{print $2, $3, $4, $5}'");
if (!$output) {
$this->logger->error("Failed to execute disk usage command");
return null;
}
list($total, $used, $available, $percentage) = explode(' ', $output);
return [
'total' => trim($total),
'used' => trim($used),
'available' => trim($available),
'percentage' => trim($percentage),
];
}
private function getServicesStatus(): array
{
$services = [
'tftpboot' => 'active',
'nginx' => 'active',
];
return $services;
}
private function getSubnetsService(): ?array
{
try {
$response = $this->curlKeaService->executeCurlCommand('config-get');
if (!$response) {
$this->logger->error('Error: No se pudo acceder al archivo de configuración Kea.');
return null;
}
$result_code = $response[0]["result"];
if ($result_code == 0) {
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
$this->logger->error("El campo 'subnet4' no está inicializado");
return null;
} else {
return $response[0]['arguments']['Dhcp4']['subnet4']; // Subredes y sus reservas
}
} else {
$this->logger->error("Error en la configuración Kea: " . $response[0]["text"]);
return null;
}
} catch (\Exception $e) {
$this->logger->error("Error al obtener la configuración de Kea DHCP: " . $e->getMessage());
return null;
}
}
/**
* @OA\Schema(
* schema="Subnet",
* type="object",
* @OA\Property(property="id", type="integer", description="The ID of the subnet"),
* @OA\Property(property="subnet", type="string", description="The name of the subnet"),
* @OA\Property(property="next-server", type="string", description="The next server in the subnet"),
* @OA\Property(property="boot-file-name", type="string", description="The boot file name for the subnet"),
* @OA\Property(
* property="reservations",
* type="array",
* @OA\Items(type="object", description="The reservations in the subnet")
* )
* )
*/
/**
* @OA\Get(
* path="/ogdhcp/v1/subnets",
* @OA\Response(
* response=200,
* description="Devuelve todas las subredes",
* ),
* @OA\Response(
* response=400,
* description="Error al obtener las subredes",
* )
* )
* @Route("/ogdhcp/v1/subnets", methods={"GET"})
*/
public function getSubnets(): JsonResponse
{
try {
$response = $this->curlKeaService->executeCurlCommand('config-get');
if (!$response) {
$responseError = 'Error: No se pudo acceder al archivo dhcpd.conf';
return new JsonResponse(['error' => $responseError], 400);
} else {
$result_code = $response[0]["result"];
if ($result_code == 0) {
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
$responseError = 'El campo \'subnet4\' no está inicializado';
return new JsonResponse(['error' => $responseError], 400);
} else {
$arrayReservations = $response[0]['arguments']['Dhcp4']['subnet4'];
return new JsonResponse($arrayReservations, 200);
}
} else {
$responseError = "Error kea configuration invalid: " . $response[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
}
}
} catch (Exception $e) {
$responseError = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
return new JsonResponse(['error' => $responseError], 400);
}
}
/**
* @OA\Post(
* path="/ogdhcp/v1/subnets",
* summary="Add a new DHCP subnet",
* @OA\RequestBody(
* description="JSON payload",
* required=true,
* @OA\JsonContent(
* type="object",
* @OA\Property(property="subnetId", type="integer", example=2),
* @OA\Property(property="mask", type="string", example="255.255.255.0"),
* @OA\Property(property="address", type="string", example="192.168.1.0"),
* @OA\Property(property="nextServer", type="string", example="192.168.1.1"),
* @OA\Property(property="bootFileName", type="string", example="pxelinux.0")
* )
* ),
* @OA\Response(
* response=200,
* description="Subnet added successfully",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="success", type="string")
* )
* ),
* @OA\Response(
* response=400,
* description="Error occurred",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string")
* )
* )
* )
* @Route("/ogdhcp/v1/subnets", methods={"POST"})
*/
public function addDhcpSubnet(Request $request): JsonResponse
{
try {
$input = json_decode($request->getContent());
$subnetId = (int) htmlspecialchars($input->subnetId);
$mask = htmlspecialchars($input->mask);
$address = htmlspecialchars($input->address);
$nextServer = htmlspecialchars($input->nextServer);
$bootFileName = htmlspecialchars($input->bootFileName);
} catch (Exception $e) {
$response["message"] = $e->getMessage();
return new JsonResponse(['error' => $response], 400);
}
try {
$response = $this->curlKeaService->executeCurlCommand('config-get');
$subnetName = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask);
$newSubnet = [
"id" => $subnetId,
"subnet" => $subnetName,
"next-server" => $nextServer,
"boot-file-name" => $bootFileName,
"reservations" => []
];
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
$response[0]['arguments']['Dhcp4']['subnet4'] = [];
}
$exists = array_reduce($response[0]['arguments']['Dhcp4']['subnet4'], function ($exists, $subnetElement) use ($subnetName, $subnetId) {
return $exists || ($subnetElement['subnet'] === $subnetName) || ($subnetElement['id'] === $subnetId);;
});
if ($exists) {
$responseError = "Error: La subred el subnet '$subnetName' ya existe en las subredes";
return new JsonResponse(['error' => $responseError], 400);
} else {
$response[0]['arguments']['Dhcp4']['subnet4'][] = $newSubnet;
// Eliminar el campo 'hash' si existe
if (isset($response[0]['arguments']['hash'])) {
unset($response[0]['arguments']['hash']);
}
$array_encoded = json_encode($response[0]['arguments']);
$configurationParsed = str_replace('\\', '', $array_encoded);
$configuration = json_decode($configurationParsed);
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
if ($responseTest[0]["result"] == 0) {
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
if ($responseSet == false || $responseSet[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseSuccess = "Configuración cargada correctamente";
return new JsonResponse(['success' => $responseSuccess], 200);
}
}
} else {
$responseError = "Error kea configuration invalid: " . $responseTest[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
}
}
} catch (Exception $e) {
$responseError = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
return new JsonResponse(['error' => $responseError], 400);
}
}
/**
* @Route("/ogdhcp/v1/subnets/{subnetId}", methods={"DELETE"})
* @OA\Delete(
* path="/ogdhcp/v1/subnets/{subnetId}",
* summary="Delete a DHCP subnet",
* @OA\Parameter(
* name="subnetId",
* in="path",
* description="ID of the subnet to delete",
* required=true,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Response(
* response=200,
* description="Subnet deleted successfully",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="success", type="string")
* )
* ),
* @OA\Response(
* response=400,
* description="Error occurred",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string")
* )
* )
* )
*/
public function deleteDhcpSubnet(Request $request): JsonResponse
{
$subnetId = (int) $request->get('subnetId');
try {
$response = $this->curlKeaService->executeCurlCommand('config-get');
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
$responseError = "Error: No hay subredes definidas";
return new JsonResponse(['error' => $responseError], 400);
}
$subnetIndex = array_search($subnetId, array_column($response[0]['arguments']['Dhcp4']['subnet4'], 'id'));
if ($subnetIndex === false) {
$responseError = "Error: La subred con el id '$subnetId' no existe";
return new JsonResponse(['error' => $responseError], 400);
} else {
unset($response[0]['arguments']['Dhcp4']['subnet4'][$subnetIndex]);
$response[0]['arguments']['Dhcp4']['subnet4'] = array_values($response[0]['arguments']['Dhcp4']['subnet4']);
$array_encoded = json_encode($response[0]['arguments']);
$configurationParsed = str_replace('\\', '', $array_encoded);
$configuration = json_decode($configurationParsed);
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
if ($responseTest[0]["result"] == 0) {
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
if ($responseSet == false || $responseSet[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseSuccess = "Subred eliminada correctamente";
return new JsonResponse(['success' => $responseSuccess], 200);
}
}
} else {
$responseError = "Error kea configuration invalid: " . $responseTest[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
}
}
} catch (Exception $e) {
$responseError = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
return new JsonResponse(['error' => $responseError], 400);
}
}
/**
* @Route("/ogdhcp/v1/subnets/{subnetId}", methods={"PUT"})
* @OA\Put(
* path="/ogdhcp/v1/subnets/{subnetId}",
* summary="Modify a DHCP subnet",
* @OA\Parameter(
* name="subnetId",
* in="path",
* description="ID of the subnet to modify",
* required=true,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\RequestBody(
* description="Data to modify the subnet",
* required=true,
* @OA\JsonContent(
* type="object",
* @OA\Property(property="mask", type="string"),
* @OA\Property(property="address", type="string"),
* @OA\Property(property="nextServer", type="string"),
* @OA\Property(property="bootFileName", type="string")
* )
* ),
* @OA\Response(
* response=200,
* description="Subnet modified successfully",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="success", type="string")
* )
* ),
* @OA\Response(
* response=400,
* description="Error occurred",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string")
* )
* )
* )
*/
public function modifyDhcpSubnet(Request $request): JsonResponse
{
$subnetId = (int) $request->get('subnetId');
try {
$input = json_decode($request->getContent());
$mask = htmlspecialchars($input->mask);
$address = htmlspecialchars($input->address);
$nextServer = htmlspecialchars($input->nextServer);
$bootFileName = htmlspecialchars($input->bootFileName);
} catch (Exception $e) {
$response["message"] = $e->getMessage();
return new JsonResponse(['error' => $response], 400);
}
try {
$response = $this->curlKeaService->executeCurlCommand('config-get');
$subnetName = $address . '/' . $this->curlKeaService->convertMaskToCIDR($mask);
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
$responseError = "Error: No hay subredes definidas";
return new JsonResponse(['error' => $responseError], 400);
}
$subnetIndex = array_search($subnetId, array_column($response[0]['arguments']['Dhcp4']['subnet4'], 'id'));
if ($subnetIndex === false) {
$responseError = "Error: La subred con el id '$subnetId' no existe";
return new JsonResponse(['error' => $responseError], 400);
} else {
$response[0]['arguments']['Dhcp4']['subnet4'][$subnetIndex] = [
"id" => $subnetId,
"subnet" => $subnetName,
"next-server" => $nextServer,
"boot-file-name" => $bootFileName,
"reservations" => []
];
$array_encoded = json_encode($response[0]['arguments']);
$configurationParsed = str_replace('\\', '', $array_encoded);
$configuration = json_decode($configurationParsed);
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
if ($responseTest[0]["result"] == 0) {
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
if ($responseSet == false || $responseSet[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseSuccess = "Subred modificada correctamente";
return new JsonResponse(['success' => $responseSuccess], 200);
}
}
} else {
$responseError = "Error kea configuration invalid: " . $responseTest[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
}
}
} catch (Exception $e) {
$responseError = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
return new JsonResponse(['error' => $responseError], 400);
}
}
/**
* @OA\Get(
* path="/ogdhcp/v1/subnets/{subnetId}/hosts",
* summary="Get all hosts in a subnet",
* @OA\Parameter(
* name="subnetId",
* in="path",
* description="The ID of the subnet",
* required=true,
* @OA\Schema(type="integer")
* ),
* @OA\Response(
* response=200,
* description="List of hosts in the subnet",
* ),
* @OA\Response(
* response=400,
* description="Error occurred",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string")
* )
* ),
* @OA\Response(
* response=500,
* description="Server error",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string")
* )
* )
* )
* @Route("/ogdhcp/v1/subnets/{subnetId}/hosts", methods={"GET"})
*/
public function getHosts($subnetId): JsonResponse
{
try {
$response = $this->curlKeaService->executeCurlCommand('config-get');
if (!$response) {
$responseError = 'Error: No se pudo acceder al archivo dhcpd.conf';
return new JsonResponse(['error' => $responseError], 400);
} else {
$result_code = $response[0]["result"];
if ($result_code == 0) {
if (!isset($response[0]['arguments']['Dhcp4']['subnet4'])) {
$responseError = 'El campo \'subnet4\' no está inicializado';
return new JsonResponse(['error' => $responseError], 400);
} else {
$subnets = $response[0]['arguments']['Dhcp4']['subnet4'];
foreach ($subnets as $subnet) {
if ($subnet['id'] == $subnetId) {
return new JsonResponse($subnet['reservations'], 200);
}
}
$responseError = 'Error: La subred con el id \'' . $subnetId . '\' no existe.';
return new JsonResponse(['error' => $responseError], 400);
}
} else {
$responseError = "Error kea configuration invalid: " . $response[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
}
}
} catch (Exception $e) {
$responseError = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
return new JsonResponse(['error' => $responseError], 400);
}
}
/**
* @OA\Post(
* path="/ogdhcp/v1/subnets/{subnetId}/hosts",
* summary="Add a DHCP host to a subnet",
* @OA\Parameter(
* name="subnetId",
* in="path",
* description="ID of the subnet to add the host to",
* required=true,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\RequestBody(
* description="Data for the new host",
* required=true,
* @OA\JsonContent(
* type="object",
* @OA\Property(property="host", type="string", example="pc11"),
* @OA\Property(property="macAddress", type="string", example="56:6f:c7:4f:00:4f"),
* @OA\Property(property="address", type="string", example="172.30.4.11")
* )
* ),
* @OA\Response(
* response=200,
* description="Host added successfully",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="success", type="string")
* )
* ),
* @OA\Response(
* response=400,
* description="Error occurred",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string")
* )
* )
* )
* @Route("/ogdhcp/v1/subnets/{subnetId}/hosts", methods={"POST"})
*/
public function addDhcpHost(Request $request): JsonResponse
{
$subnetId = (int) $request->get('subnetId');
try {
$input = json_decode($request->getContent());
$host = htmlspecialchars($input->host);
$macAddress = htmlspecialchars($input->macAddress);
$address = htmlspecialchars($input->address);
} catch (Exception $e) {
$response["message"] = $e->getMessage();
return new JsonResponse(['error' => $response], 400);
}
try {
$response = $this->curlKeaService->executeCurlCommand('config-get');
$newHost = [
"hostname" => $host,
"hw-address" => $macAddress,
"ip-address" => $address
];
$subnetFound = false;
foreach ($response[0]['arguments']['Dhcp4']['subnet4'] as &$subnet) {
if ($subnet['id'] == $subnetId) {
$subnetFound = true;
if (!isset($subnet['reservations'])) {
$subnet['reservations'] = [];
}
$exists = array_reduce($subnet['reservations'], function ($exists, $reservation) use ($host) {
return $exists || ($reservation['hostname'] === $host);
});
if ($exists) {
$responseError = "Error: El host con el hostname '$host' ya existe en las reservaciones.";
return new JsonResponse(['error' => $responseError], 400);
} else {
$subnet['reservations'][] = $newHost;
break;
}
}
}
if (!$subnetFound) {
$responseError = "Error: No se encontró la subnet con id '$subnetId'.";
return new JsonResponse(['error' => $responseError], 400);
}
$array_encoded = json_encode($response[0]['arguments']);
$configurationParsed = str_replace('\\', '', $array_encoded);
$configuration = json_decode($configurationParsed);
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
if ($responseTest[0]["result"] == 0) {
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
if ($responseSet == false || $responseSet[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseSuccess = "Configuración cargada correctamente";
return new JsonResponse(['success' => $responseSuccess], 200);
}
}
} else {
$responseError = "Error kea configuration invalid: " . $responseTest[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
}
} catch (Exception $e) {
$responseError = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
return new JsonResponse(['error' => $responseError], 400);
}
}
/**
* @OA\Delete(
* path="/ogdhcp/v1/subnets/{subnetId}/hosts",
* summary="Delete a DHCP host from a specific subnet",
* @OA\Parameter(
* name="subnetId",
* in="path",
* description="The ID of the subnet",
* required=true,
* @OA\Schema(type="integer")
* ),
* @OA\RequestBody(
* description="Data for the host to delete",
* required=true,
* @OA\JsonContent(
* type="object",
* @OA\Property(property="host", type="string", example="pc11")
* )
* ),
* @OA\Response(
* response=200,
* description="Host deleted successfully",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="success", type="string")
* )
* ),
* @OA\Response(
* response=400,
* description="Error occurred",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string")
* )
* )
* )
* @Route("/ogdhcp/v1/subnets/{subnetId}/hosts", methods={"DELETE"})
*/
public function deleteDhcpHost(Request $request, $subnetId): JsonResponse
{
try {
$input = json_decode($request->getContent());
$host = htmlspecialchars($input->host);
} catch (Exception $e) {
$response["message"] = $e->getMessage();
return new JsonResponse(['error' => $response], 400);
}
try {
$response = $this->curlKeaService->executeCurlCommand('config-get');
$subnetFound = false;
foreach ($response[0]['arguments']['Dhcp4']['subnet4'] as &$subnet) {
if ($subnet['id'] == $subnetId) {
$subnetFound = true;
if (!isset($subnet['reservations'])) {
$subnet['reservations'] = [];
}
foreach ($subnet['reservations'] as $key => $reservation) {
if (isset($reservation['hostname']) && $reservation['hostname'] === $host) {
unset($subnet['reservations'][$key]);
$subnet['reservations'] = array_values($subnet['reservations']);
break;
}
}
}
}
if ($subnetFound) {
$array_encoded = json_encode($response[0]['arguments']);
$configurationParsed = str_replace('\\', '', $array_encoded);
$configuration = json_decode($configurationParsed);
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
if ($responseTest[0]["result"] == 0) {
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
if ($responseSet == false || $responseSet[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseSuccess = "Configuración cargada correctamente";
return new JsonResponse(['success' => $responseSuccess], 200);
}
}
} else {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseTest[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
}
} else {
$responseError = "Error: El host con el hostname '$host' no existe en las reservaciones.";
return new JsonResponse(['error' => $responseError], 400);
}
} catch (Exception $e) {
$responseError = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
return new JsonResponse(['error' => $responseError], 400);
}
}
/**
* @OA\Put(
* path="/ogdhcp/v1/subnets/{subnetId}/hosts",
* summary="Update a DHCP host",
* @OA\Parameter(
* name="subnetId",
* in="path",
* description="The ID of the subnet",
* required=true,
* @OA\Schema(type="integer")
* ),
* @OA\RequestBody(
* description="Data for the host to update",
* required=true,
* @OA\JsonContent(
* type="object",
* @OA\Property(property="host", type="string", example="pc11"),
* @OA\Property(property="oldMacAddress", type="string", example="56:6f:c7:4f:00:4f"),
* @OA\Property(property="oldAddress", type="string", example="192.168.1.11"),
* @OA\Property(property="macAddress", type="string", example="56:6f:c7:4f:01:01"),
* @OA\Property(property="address", type="string", example="192.168.1.11")
* )
* ),
* @OA\Response(
* response=200,
* description="Host updated successfully",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="success", type="string")
* )
* ),
* @OA\Response(
* response=400,
* description="Error occurred",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="error", type="string")
* )
* )
* )
*
* @Route("/ogdhcp/v1/subnets/{subnetId}/hosts", methods={"PUT"})
*/
public function updateDhcpHost(Request $request, $subnetId): JsonResponse
{
try {
$input = json_decode($request->getContent());
$host = htmlspecialchars($input->host);
$oldMacAddress = htmlspecialchars($input->oldMacAddress);
$oldAddress = htmlspecialchars($input->oldAddress);
$macAddress = htmlspecialchars($input->macAddress);
$address = htmlspecialchars($input->address);
} catch (Exception $e) {
$response["message"] = $e->getMessage();
return new JsonResponse(['error' => $response], 400);
}
try {
$response = $this->curlKeaService->executeCurlCommand('config-get');
$subnetFound = false;
$hostFound = false;
foreach ($response[0]['arguments']['Dhcp4']['subnet4'] as &$subnet) {
if ($subnet['id'] == $subnetId) {
$this->logger->info('FOUND SUBNET');
$subnetFound = true;
if (!isset($subnet['reservations'])) {
$subnet['reservations'] = [];
}
foreach ($subnet['reservations'] as &$reservation) {
$this->logger->info('LOOKING FOR HOST');
if ($reservation['hw-address'] == $oldMacAddress && $reservation['ip-address'] == $oldAddress) {
$this->logger->info('FOUND HOST');
$hostFound = true;
$reservation['hw-address'] = $macAddress;
$reservation['ip-address'] = $address;
$reservation['hostname'] = $host;
break;
}
}
}
}
if ($subnetFound && $hostFound) {
$this->logger->info('UPDATING HOST');
$array_encoded = json_encode($response[0]['arguments']);
$configurationParsed = str_replace('\\', '', $array_encoded);
$configuration = json_decode($configurationParsed);
$responseTest = $this->curlKeaService->executeCurlCommand('config-test', $configuration);
if ($responseTest[0]["result"] == 0) {
$responseSet = $this->curlKeaService->executeCurlCommand('config-set', $configuration);
if ($responseSet == false || $responseSet[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseSet[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseSuccess = "Configuración cargada correctamente";
return new JsonResponse(['success' => $responseSuccess], 200);
}
}
} else {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseTest[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
}
} elseif (!$subnetFound) {
$responseError = "Error: La subred con el id '$subnetId' no existe.";
return new JsonResponse(['error' => $responseError], 400);
} elseif (!$hostFound) {
$responseError = "Error: La IP " . $oldAddress . " y la MAC " . $oldMacAddress . " no existe en las reservaciones.";
return new JsonResponse(['error' => $responseError], 400);
}
} catch (Exception $e) {
$responseError = "Error al obtener la configuración de Kea DHCP: " . $e->getMessage();
return new JsonResponse(['error' => $responseError], 400);
}
}
public function restoreDhcpConfiguration(): JsonResponse
{
$backup_dir = '/opt/opengnsys/etc/kea/backup';
try {
$backup_files = glob($backup_dir . '/*.conf');
if (empty($backup_files)) {
$response = "No se encontraron archivos de backup";
return new JsonResponse(['error' => $response], 400);
} else {
usort($backup_files, function ($a, $b) {
return filemtime($b) - filemtime($a);
});
$backup_file = reset($backup_files);
$config = file_get_contents($backup_file);
$configuration = json_decode($config);
$test_command = 'config-test';
$test_output = $this->curlKeaService->executeCurlCommand($test_command, $configuration);
if ($test_output == false || $test_output[0]["result"] != 0) {
$responseError = "Error al comprobar la configuración de Kea: " . $test_output[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$set_command = 'config-set';
$set_output = $this->curlKeaService->executeCurlCommand($set_command, $configuration, false);
if ($set_output == false || $set_output[0]["result"] != 0) {
$responseError = "Error al guardar la última configuración de Kea: " . $set_output[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
unlink($backup_file);
$responseWrite = $this->curlKeaService->executeCurlCommand('config-write', $configuration);
if ($responseWrite == false || $responseWrite[0]["result"] != 0) {
$responseError = "Error al guardar la configuración en Kea DHCP: " . $responseWrite[0]["text"];
return new JsonResponse(['error' => $responseError], 400);
} else {
$responseSuccess = "Configuración cargada correctamente";
return new JsonResponse(['success' => $responseSuccess], 200);
}
}
}
}
} catch (Exception $e) {
$responseError = "Error al restaurar la configuración: " . $e->getMessage();
return new JsonResponse(['error' => $responseError], 400);
}
}
}

View File

@ -28,8 +28,7 @@ class CurlKeaService
} else {
return "Error: Comando no válido";
}
//f (($command == 'config-set' || $command == 'config-write') && $create_backup) {
if ($command == 'config-set' && $create_backup) {
if (($command == 'config-set' || $command == 'config-write') && $create_backup) {
$this->backupConfig();
}
$jsonData = json_encode($requestData);
@ -82,7 +81,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');
}

121
tests/API-dhcp/Jenkinsfile vendored 100644
View File

@ -0,0 +1,121 @@
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'
}
}
}
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' | sed 's/^[^a-zA-Z]*//' | sed 's/[[:space:]]*$//')
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: /'
'''
}
}
}
stage('Run API tests') {
steps {
echo 'Running API tests'
// 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 {
script {
def userCause = currentBuild.rawBuild.getCause(hudson.model.Cause$UserIdCause)
if (userCause != null) {
// Si fue lanzado manualmente, obtener el usuario y su correo desde las propiedades de Jenkins
def userId = userCause.getUserId()
def userEmail = getUserEmail(userId)
if (userEmail) {
echo "El correo del usuario que lanzó el build manualmente es: ${userEmail}"
// Enviar correo al usuario que lanzó el build manualmente
mail to: "${userEmail}",
subject: "Jenkins Job Completed (Manual): ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: """
El job '${env.JOB_NAME}' con número de build ${env.BUILD_NUMBER} ha finalizado (ejecutado manualmente).
Estado: ${currentBuild.currentResult}
Revisa los detalles del build en: ${env.BUILD_URL}
"""
} else {
echo "No se pudo encontrar un correo electrónico para el usuario: ${userId}"
}
} else {
// Si fue lanzado automáticamente, obtener el correo del committer
def committerEmail = sh(
script: 'git log -1 --pretty=format:"%ae"',
returnStdout: true
).trim()
echo "El build fue lanzado automáticamente. Correo del committer: ${committerEmail}"
// Enviar correo al committer
mail to: "${committerEmail}",
subject: "Jenkins Job Completed (Automático): ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: """
El job '${env.JOB_NAME}' con número de build ${env.BUILD_NUMBER} ha finalizado (ejecutado automáticamente).
Estado: ${currentBuild.currentResult}
Revisa los detalles del build en: ${env.BUILD_URL}
"""
}
}
}
}
}
@NonCPS
def getUserEmail(userId) {
def jenkinsInstance = jenkins.model.Jenkins.getInstanceOrNull()
if (jenkinsInstance != null) {
def user = jenkinsInstance.getUser(userId)
return user.getProperty(jenkins.plugins.mailer.tasks.Mailer.UserProperty)?.getAddress()
}
return null
}

163
tests/API-dhcp/Vagrantfile vendored 100644
View File

@ -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

View File

@ -0,0 +1,104 @@
// This is a basic configuration for the Kea Control Agent.
//
// This is just a very basic configuration. Kea comes with large suite (over 30)
// of configuration examples and extensive Kea User's Guide. Please refer to
// those materials to get better understanding of what this software is able to
// do. Comments in this configuration file sometimes refer to sections for more
// details. These are section numbers in Kea User's Guide. The version matching
// your software should come with your Kea package, but it is also available
// in ISC's Knowledgebase (https://kea.readthedocs.io; the direct link for
// the stable version is https://kea.readthedocs.io/).
//
// This configuration file contains only Control Agent's configuration.
// If configurations for other Kea services are also included in this file they
// are ignored by the Control Agent.
{
// This is a basic configuration for the Kea Control Agent.
// RESTful interface to be available at http://127.0.0.1:8000/
"Control-agent": {
"http-host": "127.0.0.1",
// If enabling HA and multi-threading, the 8000 port is used by the HA
// hook library http listener. When using HA hook library with
// multi-threading to function, make sure the port used by dedicated
// listener is different (e.g. 8001) than the one used by CA. Note
// the commands should still be sent via CA. The dedicated listener
// is specifically for HA updates only.
"http-port": 8000,
// Specify location of the files to which the Control Agent
// should connect to forward commands to the DHCPv4, DHCPv6
// and D2 servers via unix domain sockets.
"control-sockets": {
"dhcp4": {
"socket-type": "unix",
"socket-name": "/run/kea/kea4-ctrl-socket"
},
"dhcp6": {
"socket-type": "unix",
"socket-name": "/run/kea/kea6-ctrl-socket"
},
"d2": {
"socket-type": "unix",
"socket-name": "/run/kea/kea-ddns-ctrl-socket"
}
},
// Specify hooks libraries that are attached to the Control Agent.
// Such hooks libraries should support 'control_command_receive'
// hook point. This is currently commented out because it has to
// point to the existing hooks library. Otherwise the Control
// Agent will fail to start.
"hooks-libraries": [
// {
// "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/control-agent-commands.so",
// "parameters": {
// "param1": "foo"
// }
// }
],
// Logging configuration starts here. Kea uses different loggers to log various
// activities. For details (e.g. names of loggers), see Chapter 18.
"loggers": [
{
// This specifies the logging for Control Agent daemon.
"name": "kea-ctrl-agent",
"output_options": [
{
// Specifies the output file. There are several special values
// supported:
// - stdout (prints on standard output)
// - stderr (prints on standard error)
// - syslog (logs to syslog)
// - syslog:name (logs to syslog using specified name)
// Any other value is considered a name of the file
"output": "stdout",
// Shorter log pattern suitable for use with systemd,
// avoids redundant information
"pattern": "%-5p %m\n"
// This governs whether the log output is flushed to disk after
// every write.
// "flush": false,
// This specifies the maximum size of the file before it is
// rotated.
// "maxsize": 1048576,
// This specifies the maximum number of rotated files to keep.
// "maxver": 8
}
],
// This specifies the severity of log messages to keep. Supported values
// are: FATAL, ERROR, WARN, INFO, DEBUG
"severity": "INFO",
// If DEBUG level is specified, this value is used. 0 is least verbose,
// 99 is most verbose. Be cautious, Kea can generate lots and lots
// of logs if told to do so.
"debuglevel": 0
}
]
}
}