Compare commits

..

2 Commits

Author SHA1 Message Date
Nicolas Arenas 9118a566c1 Updated changelog
testing/ogcore-api/pipeline/head There was a failure building this commit Details
testing/ogcore-api/pipeline/pr-main Build started... Details
ogcore-debian-package/pipeline/head This commit looks good Details
2025-03-19 12:09:37 +01:00
Nicolas Arenas b47a998007 Publishing released packages
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-03-19 12:07:32 +01:00
275 changed files with 1414 additions and 8898 deletions

View File

@ -20,7 +20,7 @@ JWT_PASSPHRASE=8b9154df37ffa91ef9186ce095324e39e50ff3b023bb1ed34383abd019ba4515
###< lexik/jwt-authentication-bundle ###
###> symfony/mercure-bundle ###
MERCURE_URL=https://localhost:3000/.well-known/mercure
MERCURE_PUBLIC_URL=https://localhost:3000/.well-known/mercure
MERCURE_URL=http://localhost:3000/.well-known/mercure
MERCURE_PUBLIC_URL=http://localhost:3000/.well-known/mercure
MERCURE_JWT_SECRET="!ChangeThisMercureHubJWTSecretKey!"
###< symfony/mercure-bundle ###

3
.gitignore vendored
View File

@ -7,7 +7,6 @@
/public/bundles/
/var/
/vendor/
api/public/bundles/
###< symfony/framework-bundle ###
#phpstorm
@ -32,5 +31,5 @@ debian/ogcore
debian/*.substvars
debian/*.log
debian/.debhelper/
debian/files

View File

@ -1,168 +1,26 @@
# Changelog
## [0.17.3] - 2025-08-04
### Improved
- Se ha añadido el filtro "jobId" a la entidad Trace.
---
## [0.17.2] - 2025-08-04
### Improved
- Se ha cambiado la respuesta de algunos endpoints que llaman al ogAgent. Ahora devuelve el job_id asociado a la traza.
---
## [0.17.1] - 2025-07-29
### Fixed
- Se ha corregido un bug que aparecia al borrar un cliente. Este error hacia que se borrara el cliente de la base de datos, pero no del DHCP ( en caso de que perteneciera a uno) y el fichero de arranque.
---
## [0.17.0] - 2025-07-20
### Added
- Se ha añadido la funcionalidad para modificar imagenes de ogGit.
---
## [0.16.0] - 2025-06-27
### Added
- Se ha cambiado el html del menu para ser compatible con HTML5.
---
## [0.15.0] - 2025-06-26
### Added
- Se ha añadido la integracion con ogGit para la gestion de imagenes.
- Se ha añadido la primera parte del sistema de cola de acciones.
- Integracion con el endpoint del agente KillJob
- Posibilidad de poder vaciar la cola de acciones.
### Fixed
- Se ha corregido un bug que hacia que al mover clientes entre aulas, diera error en caso de que el cliente no tuviera PXE asignado.
---
## [0.14.2] - 2025-06-09
### Improved
- Cambio en el template base del menu. Ahora apunta a los script de python de manera correcta.
---
## [0.14.1] - 2025-06-09
### Fixed
- Se han corregido los mensajes de error que se envian cuando las APIs de los modulos no estan disponibles.
- Se ha corregido un bug en la herencia de datos entre aulas y grupos, que hacia que no se almacenaran los datos de manera correcta.
---
## [0.14.0] - 2025-06-02
### Added
- Se ha añadido la funcionalidad de mover equipos entre aulas y grupos.
- Se ha añadido la funcionalidad para eliminar imagen cache.
- Se ha añadido la funcionalidad para iniciar sesion.
### Improved
- Se ha cambiado la restriccion que comprobaba los puertos de MULTICAST.
- Se ha modificado el tiempo en el script, que se encarga de comprobar el estado de los equipos. Ahora es de 1 min en lugar de 3.
### Fixed
- Se ha corregido un bug que hacia que al modificar un cliente o eliminarlo, no se actualizaba su estado en la subred.
- Se ha corregido un bug que hacia que al modificar un cliente, no se actualizara su fichero de arranque.
---
## [0.13.1] - 2025-05-23
### Fixed
- Variable de entorno "SSl_ENABLED" desactivada por defecto.
---
## [0.13.0] - 2025-05-20
### Added
- Se ha creado la base para la comunicacion TLS con el agente.
### Improved
- Refactorizacion de la API para la gestion de llamadas al agente
### Fixed
- Se ha corregido un bug que hacia que no se eliminara la imagen al particionar.
---
## [0.12.1] - 2025-05-14
### Improved
- Se ha eliminado la restriccion en el formulario de crear/editar repositorio, que hacia que la comprobara el formato de IP. Ahora tambien puede ser DNS.
- Mejora en el script de ejecutar tareas.
- Ahora al editar la mac de un cliente, se borra el fichero de arranque antiguo.
- Se ha añadido una restriccion en plantillas para que tan solo haya 1 por defecto
---
## [0.12.0] - 2025-05-13
### Added
- Se ha añadido nueva API para poder gestionar las tareas y acciones programadas.
- Se ha añadido un nuevo campo en plantillas (defecto) el cual nos permite tener una plantilla por defecto en caso de que se elimine una.
- Se ha comenzado la integracion con ogGit.
### Improved
- Mejorado el comportamiento de la API al crear una imagen. Ahora se guardan datos del pc de origen.
### Fixed
- Se ha corregido el bug en la creacion de clientes masivos donde no se le asignaba la plantilla PXE.
- Se ha corregido un bug en el DTO de clientes, que hacia que PHP diera un timeout por bucle infinito.
---
## [0.11.2] - 2025-04-23
### Fixed
- Se ha cambiado la forma en guardar la fecha al recibir "ping" de los clientes.
---
## [0.11.1] - 2025-04-16
### Fixed
- Se ha corregido un error al crear imagen versionada. Si la particion de origen era diferente, no dejaba crear.
- Error en la transmision de imagenes. No se actualizaba con la imagen versionada, si no con la canonica.
---
## [0.11.0] - 2025-04-11
### Added
- Se ha añadido funcionalidad para renombrar imagenes en ogRepository. Nuevo sistema de versionado.
- Se ha añadido la integracion con el ogAgent para poder ejecutar scripts.
- Se ha añadido el poder añadir descripcion a una imagen.
- Se han añadido 2 nuevos campos en la gestion de los repositorios: usuario y puerto ssh.
- Se ha añadido funcionalidad para poder gestionar el estado de un equipo de manera automatica. En caso de no haber conexion con el cliente, la web sera notificada en un tiempo maximo de 5 min.
### Improved
- Se han modificado los logs para que puedan "salir" por syslog ademas de por fichero.
### Fixed
- Se ha corregido el bug que hacia que cuando habia demasiados clientes, no se mostraran en pantalla debido a un error de memoria.
---
## [0.10.1] - 2025-03-25
### Improved
- Se ha modificado el script de creación de usuarios, añadiendole la opcion del tipo de visionalizacion por defecto de la vista "grupos".
## [0.10.0] - 2025-03-25
### Added
- Nuevo endpoint ogRepository. Convertir imagen en imagen virtual.
- Nuevo endpoint ogRepository. Importar imágenes externas al sistema.
- Nuevo método para desplegar imagenes sin cache.
---
## [0.9.5] - 2025-03-19
### Added
- Jenkinsfile updated to publish in repo
---
## [0.9.4] - 2025-03-17
### Fixed
- Mercure service behind nginx server for containers, expose port in docker compose for nginx
---
## [0.9.3] - 2025-03-17
### Fixed
- Mercure service behind nginx server for containers
---
## [0.9.2] - 2025-03-12
### Fixed
- Added mercure service in docker compose file for deployments.
---
## [0.9.1] - 2025-03-12
### Fixed
### 🐛 Fixed
- Corrección en la cancelacion de transmisiones p2p.
---
## [0.9.0] - 2025-03-04
### Added
### 🔹 Added
- Nueva funcionalidad para tener notificaciones en tiempo real. Instalación de bundle "Mercure".
- Creacion de EventListener en Symfony, para publicar mensajes en Mercure, cuando se realicen cambios en la base de datos ( cambio de estado en lo equipos, y trazas).
- Nuevo endpoint "backup image". Integracion con ogRepository.
@ -172,24 +30,24 @@
- Nueva funcionalidad para cancelar despliegues de imagenes.
- Añadido nuevo campo "cancelado" en trazas.
### Changed
### Changed
- Cambios en logs. Cambios en salida (stderror -> file.log)
- Modulo DHCP. Añadir equipos, ahora se gestiona con una unica llamada a la API.
- Acciones masivas en equipos. Se ha cambiado la respuesta para que no fallen las peticiones si uno o mas equipos no da respuesta.
---
## [0.8.1] - 2025-02-25
### Fixed
### 🐛 Fixed
- Corrección de bug en el deploy de imágenes
---
## [0.8.0] - 2025-01-10
### Added
### 🔹 Added
- Nuevos campos en "aulas" para la jerarquia en clientes.
- Nueva funcionalidad "imagen global". Integracion con ogRepository.
### Changed
### Changed
- Limpieza en campos "name" y "date" de ogLive. Es necesario parsear el campo "filename" para facilitar el uso al usuario en la web.
### 🐛 Fixed
- Corrección de bug que impedia borrar un cliente si tenia una traza enlazada.
@ -197,7 +55,7 @@
## [0.7.3] - 2025-01-03
### Added
### 🔹 Added
- Adaptados cambios en los endpoints para multiseleccion de clientes.
- Se agregó la funcionalidad de importar/exportar. Integración con ogRepository.
- Se agregó la funcionalidad de borrar imágenes. Integración con ogRepository.
@ -212,5 +70,4 @@
- **Added**: Secciones con nuevas características.
- **Fixed**: Corrección de errores y bugs.
- **Changed**: Modificaciones o mejoras en funcionalidades existentes.
- **Improved**: Mejoras en funcionalidades existentes.
- **Removed**: Funcionalidades o dependencias eliminadas.

View File

@ -48,23 +48,16 @@ pipeline {
}
}
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/ogcore")
dir("${env.BUILD_DIR}") {
sh '''
composer require symfony/flex
dpkg-buildpackage -us -uc
mkdir -p ../artifacts && mv ../*.deb ../*.changes ../*.buildinfo ../artifacts/
ssh aptly@172.17.8.68 "rm -rf /var/tmp/opengnsys/debian-repo/ogcore && mkdir -p /var/tmp/opengnsys/debian-repo/ogcore"
scp -r ../artifacts/* aptly@172.17.8.68:/var/tmp/opengnsys/debian-repo/ogcore
'''
}
}
}
@ -76,24 +69,7 @@ pipeline {
}
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/ogcore', '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/ogcore', 'nightly', versionPattern)
}
sh "aptly repo add opengnsys-devel /var/tmp/opengnsys/debian-repo/*.deb"
}
}
}

View File

@ -32,7 +32,7 @@ resources:
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\ChangeOrganizationalUnitInput
uriTemplate: /clients/change-organizational-unit
uriTemplate: /clients/change-organizational-units
controller: App\Controller\ChangeOrganizationalUnitAction
agent_status:
@ -50,34 +50,6 @@ resources:
uriTemplate: /clients/server/{uuid}/get-pxe
controller: App\Controller\OgBoot\PxeBootFile\GetAction
boot_client:
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\BootClientsInput
uriTemplate: /clients/server/boot-client
controller: App\Controller\OgAgent\LoginAction
remove_cache_image:
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\BootClientsInput
uriTemplate: /clients/server/remove-cache-image
controller: App\Controller\OgAgent\RemoveCacheImageAction
hardware_inventory:
class: ApiPlatform\Metadata\Post
method: POST
input: false
uriTemplate: /clients/server/{uuid}/hardware-inventory
controller: App\Controller\OgAgent\HardwareInventoryAction
software_inventory:
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\SoftwareInventoryPartitionInput
uriTemplate: /clients/server/{uuid}/software-inventory
controller: App\Controller\OgAgent\SoftwareInventoryAction
reboot_client:
class: ApiPlatform\Metadata\Post
method: POST

View File

@ -7,8 +7,6 @@ resources:
groups: ['default', 'command:read']
denormalizationContext:
groups: ['command:write']
order:
id: 'DESC'
operations:
ApiPlatform\Metadata\GetCollection:
provider: App\State\Provider\CommandProvider
@ -30,8 +28,9 @@ resources:
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\CommandExecuteInput
uriTemplate: /commands/run-script
controller: App\Controller\OgAgent\RunScriptAction
uriTemplate: /commands/{uuid}/execute
controller: App\Controller\CommandExecuteAction
properties:
App\Entity\Command:
id:

View File

@ -1,32 +0,0 @@
resources:
App\Entity\CommandTaskSchedule:
processor: App\State\Processor\CommandTaskScheduleProcessor
input: App\Dto\Input\CommandTaskScheduleInput
output: App\Dto\Output\CommandTaskScheduleOutput
normalizationContext:
groups: ['default', 'command-task-schedule:read']
denormalizationContext:
groups: ['command-task-schedule:write']
operations:
ApiPlatform\Metadata\GetCollection:
provider: App\State\Provider\CommandTaskScheduleProvider
filters:
- 'api_platform.filter.command_task_schedule.order'
- 'api_platform.filter.command_task_schedule.search'
- 'api_platform.filter.command_task_schedule.boolean'
ApiPlatform\Metadata\Get:
provider: App\State\Provider\CommandTaskScheduleProvider
ApiPlatform\Metadata\Put:
provider: App\State\Provider\CommandTaskScheduleProvider
ApiPlatform\Metadata\Patch:
provider: App\State\Provider\CommandTaskScheduleProvider
ApiPlatform\Metadata\Post: ~
ApiPlatform\Metadata\Delete: ~
properties:
App\Entity\CommandTaskSchedule:
id:
identifier: false
uuid:
identifier: true

View File

@ -1,32 +0,0 @@
resources:
App\Entity\CommandTaskScript:
processor: App\State\Processor\CommandTaskScriptProcessor
input: App\Dto\Input\CommandTaskScriptInput
output: App\Dto\Output\CommandTaskScriptOutput
normalizationContext:
groups: ['default', 'command-task-script:read']
denormalizationContext:
groups: ['command-task-script:write']
operations:
ApiPlatform\Metadata\GetCollection:
provider: App\State\Provider\CommandTaskScriptProvider
filters:
- 'api_platform.filter.command_task_script.order'
- 'api_platform.filter.command_task_script.search'
- 'api_platform.filter.command_task_script.boolean'
ApiPlatform\Metadata\Get:
provider: App\State\Provider\CommandTaskScriptProvider
ApiPlatform\Metadata\Put:
provider: App\State\Provider\CommandTaskScriptProvider
ApiPlatform\Metadata\Patch:
provider: App\State\Provider\CommandTaskScriptProvider
ApiPlatform\Metadata\Post: ~
ApiPlatform\Metadata\Delete: ~
properties:
App\Entity\CommandTaskScript:
id:
identifier: false
uuid:
identifier: true

View File

@ -1,109 +0,0 @@
resources:
App\Entity\GitRepository:
processor: App\State\Processor\GitRepositoryProcessor
input: App\Dto\Input\GitRepositoryInput
output: App\Dto\Output\GitRepositoryOutput
normalizationContext:
groups: ['default', 'git-repository:read']
denormalizationContext:
groups: ['git-repository:write']
operations:
ApiPlatform\Metadata\GetCollection:
provider: App\State\Provider\GitRepositoryProvider
filters:
- 'api_platform.filter.git_repository.order'
- 'api_platform.filter.git_repository.search'
openapiContext:
summary: 'Obtener lista de repositorios Git'
description: 'Obtiene todos los repositorios Git de un servidor específico'
parameters:
- name: 'repository'
in: 'query'
required: true
schema:
type: 'integer'
description: 'ID del ImageRepository que contiene los repositorios'
- name: 'page'
in: 'query'
schema:
type: 'integer'
default: 1
description: 'Número de página'
- name: 'limit'
in: 'query'
schema:
type: 'integer'
default: 10
description: 'Elementos por página'
ApiPlatform\Metadata\Get:
provider: App\State\Provider\GitRepositoryProvider
openapiContext:
summary: 'Obtener un repositorio Git específico'
description: 'Obtiene un repositorio Git específico por su nombre'
parameters:
- name: 'repository'
in: 'query'
required: true
schema:
type: 'integer'
description: 'ID del ImageRepository'
ApiPlatform\Metadata\Put:
provider: App\State\Provider\GitRepositoryProvider
openapiContext:
summary: 'Actualizar un repositorio Git'
description: 'Actualiza un repositorio Git existente en el servidor externo'
parameters:
- name: 'repository'
in: 'query'
required: true
schema:
type: 'integer'
description: 'ID del ImageRepository'
ApiPlatform\Metadata\Patch:
provider: App\State\Provider\GitRepositoryProvider
openapiContext:
summary: 'Actualizar parcialmente un repositorio Git'
description: 'Actualiza parcialmente un repositorio Git existente'
parameters:
- name: 'repository'
in: 'query'
required: true
schema:
type: 'integer'
description: 'ID del ImageRepository'
ApiPlatform\Metadata\Post:
openapiContext:
summary: 'Crear un nuevo repositorio Git'
description: 'Crea un nuevo repositorio Git en el servidor externo. El ID del ImageRepository debe incluirse en el body del request.'
ApiPlatform\Metadata\Delete:
openapiContext:
summary: 'Eliminar un repositorio Git'
description: 'Elimina un repositorio Git del servidor externo'
parameters:
- name: 'repository'
in: 'query'
required: true
schema:
type: 'integer'
description: 'ID del ImageRepository'
git_deploy_image:
shortName: Git Repository
description: Deploy Git image
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\DeployGitImageInput
uriTemplate: /git-repositories/deploy-image
controller: App\Controller\DeployGitImageAction
properties:
App\Entity\GitRepository:
id:
identifier: false
name:
identifier: true

View File

@ -56,22 +56,6 @@ resources:
uriTemplate: /image-image-repositories/{uuid}/backup-image
controller: App\Controller\OgRepository\Image\BackupImageAction
convert_image_to_virtual_image_ogrepository:
shortName: OgRepository Server
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\ConvertImageToVirtualInput
uriTemplate: /image-image-repositories/{uuid}/convert-image-to-virtual
controller: App\Controller\OgRepository\Image\ConvertImageToVirtualAction
rename_image_ogrepository:
shortName: OgRepository Server
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\RenameImageInput
uriTemplate: /image-image-repositories/{uuid}/rename-image
controller: App\Controller\OgRepository\Image\RenameAction
trash_delete_image_ogrepository:
shortName: OgRepository Server
description: Delete Image in OgRepository
@ -104,7 +88,7 @@ resources:
description: Export Image in OgRepository
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\TransferGlobalImageInput
input: App\Dto\Input\ExportImportImageRepositoryInput
uriTemplate: /image-image-repositories/{uuid}/transfer-image
controller: App\Controller\OgRepository\Image\TransferAction
@ -117,15 +101,6 @@ resources:
uriTemplate: /image-image-repositories/server/{uuid}/status
controller: App\Controller\OgRepository\Image\GetStatusAction
transfer_global_image_repository:
shortName: OgRepository Server
description: Transfer Global Image in OgRepository
class: ApiPlatform\Metadata\Post
method: POST
input: false
uriTemplate: /image-image-repositories/server/{uuid}/transfer-global
controller: App\Controller\OgRepository\Image\TransferGlobalAction
properties:
App\Entity\ImageImageRepository:
id:

View File

@ -30,7 +30,7 @@ resources:
method: POST
input: false
uriTemplate: /image-repositories/server/{uuid}/sync
controller: App\Controller\OgRepository\Image\SyncAction
controller: App\Controller\OgRepository\SyncAction
wol_client:
class: ApiPlatform\Metadata\Post
@ -46,7 +46,7 @@ resources:
method: POST
input: false
uriTemplate: /image-repositories/server/{uuid}/get-collection
controller: App\Controller\OgRepository\Image\GetCollectionAction
controller: App\Controller\OgRepository\GetCollectionAction
images_ogrepository_status:
shortName: OgRepository Server
@ -57,50 +57,14 @@ resources:
uriTemplate: /image-repositories/server/{uuid}/status
controller: App\Controller\OgRepository\StatusAction
import_image_ogrepository:
export_image_ogrepository:
shortName: OgRepository Server
description: Export Image in OgRepository
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\ImportImageRepositoryInput
uriTemplate: /image-repositories/{uuid}/import-image
controller: App\Controller\OgRepository\Image\ImportAction
convert_image_ogrepository:
shortName: OgRepository Server
description: Convert Image in OgRepository
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\ConvertImageRepositoryInput
uriTemplate: /image-repositories/{uuid}/convert-image
controller: App\Controller\OgRepository\Image\ConvertAction
get_collection_images_oggit:
shortName: OgRepository Server
description: Get collection of image in OgRepository
class: ApiPlatform\Metadata\Get
method: GET
input: false
uriTemplate: /image-repositories/server/git/{uuid}/get-collection
controller: App\Controller\OgRepository\Git\GetCollectionAction
git_repository_commits:
shortName: OgRepository Server
description: Get commits from a specific branch of a Git repository
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\GetCommitsInput
uriTemplate: /image-repositories/server/git/{uuid}/commits
controller: App\Controller\OgRepository\Git\GetCommitsAction
git_repository_branches:
shortName: OgRepository Server
description: Get branches from a Git repository
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\GetBranchesInput
uriTemplate: /image-repositories/server/git/{uuid}/branches
controller: App\Controller\OgRepository\Git\GetBranchesAction
input: App\Dto\Input\ExportImportImageRepositoryInput
uriTemplate: /image-repositories/{uuid}/export-image
controller: App\Controller\OgRepository\Image\ExportAction
properties:
App\Entity\ImageRepository:

View File

@ -4,7 +4,6 @@ resources:
input: App\Dto\Input\PartitionPostInput
output: App\Dto\Output\PartitionOutput
order:
diskNumber: 'ASC'
partitionNumber: 'ASC'
normalizationContext:
groups: ['default', 'partition:read']

View File

@ -13,7 +13,6 @@ resources:
filters:
- 'api_platform.filter.software.order'
- 'api_platform.filter.software.search'
- 'software.software_profile_filter'
ApiPlatform\Metadata\Get:
provider: App\State\Provider\SoftwareProvider

View File

@ -9,8 +9,6 @@ resources:
filters:
- 'api_platform.filter.trace.order'
- 'api_platform.filter.trace.search'
- 'api_platform.filter.trace.date'
ApiPlatform\Metadata\Get:
provider: App\State\Provider\TraceProvider
@ -23,24 +21,6 @@ resources:
uriTemplate: /traces/server/{uuid}/cancel
controller: App\Controller\OgRepository\Image\CancelTransmissionAction
cancel_multiple_traces:
shortName: Trace Server
description: Cancel Multiple Traces in OgRepository
controller: App\Controller\CancelMultipleTracesAction
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\CancelMultipleTracesInput
uriTemplate: /traces/cancel-multiple
kill_job:
shortName: Kill Job
description: Kill Job in OgAgent
controller: App\Controller\OgAgent\KillJobAction
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\KillJobInput
uriTemplate: /traces/{uuid}/kill-job
order:
createdAt: DESC

View File

@ -12,7 +12,6 @@ framework:
handler_id: null
cookie_secure: auto
cookie_samesite: lax
storage_factory_id: session.storage.factory.native
#esi: true
#fragments: true

View File

@ -15,12 +15,6 @@ when@dev:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!console"]
syslog:
type: syslog
ident: "ogcore"
level: info
formatter: App\Formatter\CustomLineFormatter
channels: ["!event"]
when@test:
monolog:
@ -44,16 +38,13 @@ when@prod:
level: error
formatter: App\Formatter\CustomLineFormatter
channels: ["!event"]
syslog:
type: syslog
ident: "ogcore"
level: error
formatter: App\Formatter\CustomLineFormatter
channels: ["!event"]
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine"]
deprecation:
type: stream
channels: [deprecation]
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: error
formatter: monolog.formatter.json

View File

@ -33,7 +33,6 @@ security:
- { path: ^/og-repository/webhook, roles: PUBLIC_ACCESS }
- { path: ^/og-lives/install/webhook, roles: PUBLIC_ACCESS }
- { path: ^/auth/refresh, roles: PUBLIC_ACCESS }
- { path: ^/validate, roles: PUBLIC_ACCESS }
- { path: ^/menu-browser, roles: PUBLIC_ACCESS }
- { path: ^/menu/, roles: PUBLIC_ACCESS }
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }

View File

@ -14,4 +14,4 @@ when@test:
intercept_redirects: false
framework:
profiler: { collect: false }
profiler: { collect: false }

View File

@ -156,13 +156,3 @@ services:
bind:
$collectionProvider: '@api_platform.doctrine.orm.state.collection_provider'
$itemProvider: '@api_platform.doctrine.orm.state.item_provider'
App\State\Provider\CommandTaskScheduleProvider:
bind:
$collectionProvider: '@api_platform.doctrine.orm.state.collection_provider'
$itemProvider: '@api_platform.doctrine.orm.state.item_provider'
App\State\Provider\CommandTaskScriptProvider:
bind:
$collectionProvider: '@api_platform.doctrine.orm.state.collection_provider'
$itemProvider: '@api_platform.doctrine.orm.state.item_provider'

View File

@ -41,52 +41,6 @@ services:
tags: [ 'api_platform.filter' ]
api_platform.filter.command.boolean:
parent: 'api_platform.doctrine.orm.boolean_filter'
arguments: [ { 'enabled': ~, 'readOnly': ~ } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.command_task.order:
parent: 'api_platform.doctrine.orm.order_filter'
arguments:
$properties: { 'id': ~, 'name': ~ }
$orderParameterName: 'order'
tags: [ 'api_platform.filter' ]
api_platform.filter.command_task.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial' } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.command_task_schedule.order:
parent: 'api_platform.doctrine.orm.order_filter'
arguments:
$properties: { 'id': ~, 'name': ~ }
$orderParameterName: 'order'
tags: [ 'api_platform.filter' ]
api_platform.filter.command_task_schedule.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial', 'commandTask.id': 'exact' } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.command_task_schedule.boolean:
parent: 'api_platform.doctrine.orm.boolean_filter'
arguments: [ { 'enabled': ~} ]
tags: [ 'api_platform.filter' ]
api_platform.filter.command_task_script.order:
parent: 'api_platform.doctrine.orm.order_filter'
arguments:
$properties: { 'id': ~, 'name': ~ }
$orderParameterName: 'order'
tags: [ 'api_platform.filter' ]
api_platform.filter.command_task_script.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial', 'commandTask.id': 'exact' } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.command_task_script.boolean:
parent: 'api_platform.doctrine.orm.boolean_filter'
arguments: [ { 'enabled': ~ } ]
tags: [ 'api_platform.filter' ]
@ -107,7 +61,7 @@ services:
api_platform.filter.image.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial', 'repository.id': 'exact', status: 'exact', type: 'exact' } ]
arguments: [ { 'id': 'exact', 'name': 'partial', 'repository.id': 'exact', status: 'exact'} ]
tags: [ 'api_platform.filter' ]
api_platform.filter.image.boolean:
@ -119,10 +73,6 @@ services:
parent: 'App\Filter\ImageSearchRepositoryFilter'
tags: [ 'api_platform.filter' ]
software.software_profile_filter:
parent: 'App\Filter\SoftwareProfileSearchSoftwareFilter'
tags: [ 'api_platform.filter' ]
api_platform.filter.og_live.order:
parent: 'api_platform.doctrine.orm.order_filter'
arguments:
@ -132,7 +82,7 @@ services:
api_platform.filter.og_live.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial', 'status': 'exact' } ]
arguments: [ { 'id': 'exact', 'name': 'partial', } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.og_live.boolean:
@ -217,7 +167,7 @@ services:
api_platform.filter.pxe_template.boolean:
parent: 'api_platform.doctrine.orm.boolean_filter'
arguments: [ { 'synchronized': ~, 'isDefault': ~ } ]
arguments: [ { 'synchronized': ~ } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.remote_calendar.order:
@ -281,7 +231,7 @@ services:
api_platform.filter.software_profile.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'description': 'partial'} ]
arguments: [ { 'id': 'exact', 'description': 'partial' } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.subnet.order:
@ -298,7 +248,7 @@ services:
api_platform.filter.trace.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'command': 'exact', 'client.id': 'exact', 'status': 'exact', 'jobId': 'exact' } ]
arguments: [ { 'id': 'exact', 'command.id': 'exact', 'client.id': 'exact', status: 'exact' } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.trace.order:
@ -308,11 +258,6 @@ services:
$orderParameterName: 'order'
tags: [ 'api_platform.filter' ]
api_platform.filter.trace.date:
parent: 'api_platform.doctrine.orm.date_filter'
arguments: [ { 'executedAt': ~, 'createdAt': ~ } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.user.order:
parent: 'api_platform.doctrine.orm.order_filter'
arguments:
@ -347,28 +292,4 @@ services:
arguments: [ { 'enabled': ~ } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.git_repository.order:
parent: 'api_platform.doctrine.orm.order_filter'
arguments:
$properties: { 'id': ~, 'name': ~ }
$orderParameterName: 'order'
tags: [ 'api_platform.filter' ]
api_platform.filter.git_repository.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial', 'description': 'partial' } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.git_image_repository.order:
parent: 'api_platform.doctrine.orm.order_filter'
arguments:
$properties: { 'id': ~, 'name': ~, 'status': ~, 'tag': ~, 'branch': ~ }
$orderParameterName: 'order'
tags: [ 'api_platform.filter' ]
api_platform.filter.git_image_repository.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial', 'status': 'exact', 'tag': 'partial', 'branch': 'partial', 'image.id': 'exact', 'repository.id': 'exact', 'gitRepository.id': 'exact' } ]
tags: [ 'api_platform.filter' ]

2
debian/control vendored
View File

@ -12,5 +12,5 @@ Depends: ${misc:Depends}, mariadb-server, systemd, nginx, libzip-dev, zip, unzip
php8.3-gd, php8.3-ldap, php8.3-mbstring, php8.3-mysql, php8.3-common,
php8.3-xml, php8.3-zip, mercure
Description: OpenGnsys Core
OgCore package is responsible about management of Opengnsys platform
This is a longer description of the ogcore package.
OpenGnsys Core is a platform for system management.

View File

@ -4,35 +4,10 @@ set -e
set -x
. /usr/share/debconf/confmodule
restore_config_if_modified() {
local new="$1"
local backup="$1.bak"
if [ -f "$backup" ]; then
if ! cmp -s "$new" "$backup"; then
echo ">>> Archivo modificado por el usuario detectado en $new"
echo " - Guardando archivo nuevo como ${new}.new"
mv -f "$new" "${new}.new"
echo " - Restaurando archivo anterior desde backup"
mv -f "$backup" "$new"
else
echo ">>> El archivo $new no ha cambiado desde la última versión, eliminando backup"
rm -f "$backup"
fi
fi
}
USER="opengnsys"
# Detectar si es una instalación nueva o una actualización
if [ "$1" = "configure" ] && [ -z "$2" ]; then
# Detectar IP de la interfaz de red asociad a la ruta por defecto.
IP=$(ip -4 route get 8.8.8.8 | grep -oP '(?<=src )[\d.]+')
echo ">>> Instalación nueva detectada."
# Solicitar credenciales solo en instalación nueva
@ -50,8 +25,7 @@ if [ "$1" = "configure" ] && [ -z "$2" ]; then
# Configuración inicial
echo ">>> Configurando base de datos y permisos"
mariadb -e "ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('root');"
mariadb -e "GRANT ALL ON *.* to 'root'@'localhost' IDENTIFIED BY 'root' WITH GRANT OPTION;"
echo ">>> Creando par de claves para JWT"
php bin/console lexik:jwt:generate-keypair --overwrite
@ -68,7 +42,6 @@ if [ "$1" = "configure" ] && [ -z "$2" ]; then
echo ">>> Configurando servidor web y servicios"
ln -s /opt/opengnsys/ogcore/etc/nginx/sites-available/ogcore.conf /etc/nginx/sites-enabled/ogcore.conf
ln -s /opt/opengnsys/ogcore/etc/nginx/sites-available/mercure.conf /etc/nginx/sites-enabled/mercure.conf
ln -s /opt/opengnsys/ogcore/etc/php/8.3/fpm/pool.d/ogcore-fpm.conf /etc/php/8.3/fpm/pool.d/ogcore-fpm.conf
ln -s /opt/opengnsys/ogcore/etc/systemd/system/og-mercure.service /etc/systemd/system/og-mercure.service
@ -80,31 +53,29 @@ if [ "$1" = "configure" ] && [ -z "$2" ]; then
systemctl restart og-mercure
systemctl restart nginx
systemctl restart php8.3-fpm
#Obteniendo bearer token
BEARER=$(curl -sk -X 'POST' 'https://localhost:8443/auth/login' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{ "username": "ogadmin", "password": "12345678" }' | jq -r .token)
# Creando nuevo repo
curl -skL -X POST 'https://localhost:8443/image-repositories' \
-H "Authorization: Bearer $BEARER" \
-H 'Content-Type: application/json' \
-d "{ \"name\": \"Repository 1\", \"ip\": \"$IP\", \"comments\": \"Repositorio creado automaticamente por oginstaller\" }"
# Solo gestionar credenciales en instalación nueva
if [ "$ADMIN_USER" == "ogadmin" ]; then
echo ">>> Cambiando contraseña de ogadmin"¡
BEARER=$(curl -sk -X 'POST' 'https://localhost:8443/auth/login' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{ "username": "ogadmin", "password": "12345678" }' | jq -r .token)
echo ">>> Cambiando contraseña de ogadmin"
OGADMIN_UUID=$(curl -skL "https://localhost:8443/users/?username=ogadmin" \
-H 'accept: application/json' \
-H "Authorization: Bearer $BEARER" | jq -r '.[0].uuid')
curl -skL -X PUT "https://localhost:8443/users/$OGADMIN_UUID/reset-password" \
-H 'accept: application/ld+json' \
-H 'Content-Type: application/ld+json' \
-H "Authorization: Bearer $BEARER" \
-d "{ \"currentPassword\": \"12345678\", \"newPassword\": \"$ADMIN_PASS\", \"repeatNewPassword\": \"$ADMIN_PASS\" }"
echo ">>> Contraseña de ogadmin cambiada."
else
echo ">>> Creando nuevo usuario administrador: $ADMIN_USER"
curl -skL --location 'https://localhost:8443/users' \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $BEARER" \
@ -112,48 +83,29 @@ if [ "$1" = "configure" ] && [ -z "$2" ]; then
echo ">>> Usuario administrador $ADMIN_USER creado."
fi
# Install crontab
echo ">>> Configurando cron para comprobar disponibilidad de clientes"
cp /opt/opengnsys/ogcore/etc/cron.d/opengnsys-check-clients /etc/cron.d/opengnsys-check-clients
chmod 644 /etc/cron.d/opengnsys-check-clients
chown root:root /etc/cron.d/opengnsys-check-clients
elif [ "$1" = "configure" ] && [ -n "$2" ]; then
echo ">>> Actualización detectada desde la versión $2"
# Restaurar archivos de configuración si han sido modificados
restore_config_if_modified "/opt/opengnsys/ogcore/etc/nginx/sites-available/ogcore.conf"
restore_config_if_modified "/opt/opengnsys/ogcore/etc/nginx/sites-available/mercure.conf"
restore_config_if_modified "/opt/opengnsys/ogcore/etc/php/8.3/fpm/pool.d/ogcore-fpm.conf"
restore_config_if_modified "/opt/opengnsys/ogcore/etc/systemd/system/og-mercure.service"
restore_config_if_modified "/opt/opengnsys/ogcore/api/env.json"
cd /opt/opengnsys/ogcore/api
echo ">>> Aplicando migraciones de base de datos"
php bin/console doctrine:migrations:migrate --no-interaction
echo ">>> Configurando servidor web y servicios"
[ ! -L /etc/nginx/sites-enabled/ogcore.conf ] && ln -s /opt/opengnsys/ogcore/etc/nginx/sites-available/ogcore.conf /etc/nginx/sites-enabled/ogcore.conf
[ ! -L /etc/php/8.3/fpm/pool.d/ogcore-fpm.conf ] && ln -s /opt/opengnsys/ogcore/etc/php/8.3/fpm/pool.d/ogcore-fpm.conf /etc/php/8.3/fpm/pool.d/ogcore-fpm.conf
[ ! -L /etc/systemd/system/og-mercure.service ] && ln -s /opt/opengnsys/ogcore/etc/systemd/system/og-mercure.service /etc/systemd/system/og-mercure.service
ln -s /opt/opengnsys/ogcore/etc/nginx/sites-available/ogcore.conf /etc/nginx/sites-enabled/ogcore.conf
ln -s /opt/opengnsys/ogcore/etc/php/8.3/fpm/pool.d/ogcore-fpm.conf /etc/php/8.3/fpm/pool.d/ogcore-fpm.conf
ln -s /opt/opengnsys/ogcore/etc/systemd/system/og-mercure.service /etc/systemd/system/og-mercure.service
echo ">>> Configurando permisos de archivos"
chown opengnsys:www-data /opt/opengnsys/
chown -R opengnsys:www-data /opt/opengnsys/ogcore
if [ ! -f /etc/cron.d/opengnsys-check-clients ]; then
echo ">>> Configurando cron para comprobar disponibilidad de clientes"
cp /opt/opengnsys/ogcore/etc/cron.d/opengnsys-check-clients /etc/cron.d/opengnsys-check-clients
chmod 644 /etc/cron.d/opengnsys-check-clients
chown root:root /etc/cron.d/opengnsys-check-clients
else
echo ">>> El archivo de cron ya existe, no se realizan cambios se ajustan permisos"
chmod 644 /etc/cron.d/opengnsys-check-clients
chown root:root /etc/cron.d/opengnsys-check-clients
fi
systemctl daemon-reload
systemctl enable og-mercure
systemctl restart og-mercure
systemctl restart nginx
systemctl restart php8.3-fpm
fi
fi
# Recargar systemd y reiniciar servicios en ambos casos

29
debian/ogcore.preinst vendored
View File

@ -2,19 +2,6 @@
set -e
backup_file_if_exists() {
local original="$1"
local backup="$1.bak"
if [ -e "$original" ]; then
echo " - Guardando backup de $original en $backup"
cp -a "$original" "$backup"
fi
}
CONFIG_FILE="/opt/opengnsys/ogcore/api/env.json"
BACKUP_FILE="/opt/opengnsys/ogcore/api/env.json.bak"
# Asegurarse de que el usuario exista
USER="opengnsys"
HOME_DIR="/opt/opengnsys"
@ -25,18 +12,4 @@ else
useradd -m -d "$HOME_DIR" -s /bin/bash "$USER"
fi
CONFIG_FILE="/opt/opengnsys/ogcore/api/env.json"
BACKUP_FILE="/opt/opengnsys/ogcore/api/env.json.bak"
# Solo hacemos backup si el archivo existe y es una actualización (posición 1 = upgrade)
if [ "$1" = "upgrade" ]; then
echo ">>> Backup de archivos de configuración reales en /opt/opengnsys"
backup_file_if_exists "/opt/opengnsys/ogcore/etc/nginx/sites-available/ogcore.conf"
backup_file_if_exists "/opt/opengnsys/ogcore/etc/nginx/sites-available/mercure.conf"
backup_file_if_exists "/opt/opengnsys/ogcore/etc/php/8.3/fpm/pool.d/ogcore-fpm.conf"
backup_file_if_exists "/opt/opengnsys/ogcore/etc/systemd/system/og-mercure.service"
backup_file_if_exists "/opt/opengnsys/ogcore/api/env.json"
fi
exit 0
exit 0

4
debian/rules vendored
View File

@ -8,5 +8,5 @@ override_dh_auto_build:
export COMPOSER_ALLOW_SUPERUSER=1
export APP_ENV=prod
dh_auto_build
COMPOSER_ALLOW_SUPERUSER=1 APP_ENV=prod composer install --no-dev --no-interaction --no-progress --optimize-autoloader
COMPOSER_ALLOW_SUPERUSER=1 APP_ENV=prod composer dump-env prod
composer dump-env prod
composer install --no-dev --no-interaction --no-progress --optimize-autoloader

View File

@ -26,8 +26,7 @@ services:
- 8443:443 # Añadir el puerto 443
volumes:
- ./public:/var/www/html/public:cached
- ./docker/certs:/etc/nginx/certs
- ./certs:/opt/opengnsys/ogcore/etc/certificates
- ./docker/certs:/etc/nginx/certs # Montar certificados en Nginx
networks:
- ogcore-network
@ -38,7 +37,6 @@ services:
dockerfile: ./docker/Dockerfile-php
volumes:
- ./:/var/www/html
- ./certs:/opt/opengnsys/ogcore/etc/certificates
depends_on:
- database
networks:

View File

@ -12,11 +12,11 @@ server {
root /var/www/html/public;
index index.html index.php;
#ssl_certificate /opt/opengnsys/ogcore/etc/certificates/ogcore.crt;
#ssl_certificate_key /opt/opengnsys/ogcore/etc/certificates/ogcore.key;
ssl_certificate /etc/nginx/certs/ogcore.uds-test.net.crt.pem;
ssl_certificate_key /etc/nginx/certs/ogcore.uds-test.net.key.pem;
location /opengnsys/rest/ous// {
rewrite ^/opengnsys/rest/ous//([0-9]+)/images /opengnsys/rest/ous/$1/images;
rewrite ^/opengnsys/rest/ous//([0-9]+)/labs /opengnsys/rest/ous/$1/labs;
@ -44,9 +44,6 @@ server {
error_log /var/log/nginx/error.log debug;
access_log /var/log/nginx/access.log;
#ssl_client_certificate /opt/opengnsys/ogcore/etc/certificates/ca.crt;
#ssl_verify_client on;
}
server {

View File

@ -1,15 +1,12 @@
{
"vars": {
"OG_DHCP_API_URL": "127.0.0.1:8081",
"OG_CORE_IP": "127.0.0.1",
"OG_LOG_IP": "127.0.0.1",
"OG_BOOT_API_URL": "192.168.68.51:8082",
"OG_DHCP_API_URL": "192.168.68.51:8081",
"OG_CORE_IP": "192.168.68.62",
"OG_LOG_IP": "192.168.68.51",
"UDS_AUTH_LOGIN": "test",
"UDS_AUTH_USERNAME": "test",
"UDS_AUTH_PASSWORD": "test",
"UDS_URL": "https:\/\/localhost:8087\/uds\/rest\/",
"SSL_ENABLED": "false",
"OG_BOOT_IP": "127.0.0.1",
"OG_BOOT_API_PORT": "8082",
"OG_BOOT_PXE_PORT": "8082"
"UDS_URL": "https:\/\/localhost:8087\/uds\/rest\/"
}
}

View File

@ -1,3 +0,0 @@
*/2 * * * * opengnsys php -d memory_limit=512M /opt/opengnsys/ogcore/api/bin/console opengnsys:check-client-availability>> /opt/opengnsys/ogcore/api/var/log/cron.log 2>&1
*/1 * * * * opengnsys php -d memory_limit=512M /opt/opengnsys/ogcore/api/bin/console opengnsys:run-scheduled-command-tasks>> /opt/opengnsys/ogcore/api/var/log/cron.log 2>&1
*/1 * * * * opengnsys php -d memory_limit=512M /opt/opengnsys/ogcore/api/bin/console opengnsys:execute-pending-traces>> /opt/opengnsys/ogcore/api/var/log/cron.log 2>&1

View File

@ -1,4 +1,4 @@
SERVER_NAME=":3001"
SERVER_NAME=":3000"
MERCURE_PUBLISHER_JWT_KEY="!ChangeThisMercureHubJWTSecretKey!"
MERCURE_SUBSCRIBER_JWT_KEY="!ChangeThisMercureHubJWTSecretKey!"
MERCURE_EXTRA_DIRECTIVES="cors_origins *"

View File

@ -1,23 +0,0 @@
server {
listen 3000 ssl http2;
listen [::]:3000 ssl http2;
ssl_certificate /opt/opengnsys/ogcore/etc/nginx/certs/ogcore.uds-test.net.crt.pem;
ssl_certificate_key /opt/opengnsys/ogcore/etc/nginx/certs/ogcore.uds-test.net.key.pem;
location / {
proxy_pass http://localhost:3001/;
proxy_read_timeout 24h;
proxy_http_version 1.1;
proxy_set_header Connection "";
# Enable fast reply in SSE
proxy_buffering off;
## Be sure to set USE_FORWARDED_HEADERS=1 to allow the hub to use those headers ##
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

View File

@ -7,16 +7,6 @@ server {
ssl_certificate /opt/opengnsys/ogcore/etc/nginx/certs/ogcore.uds-test.net.crt.pem;
ssl_certificate_key /opt/opengnsys/ogcore/etc/nginx/certs/ogcore.uds-test.net.key.pem;
location ~ ^/pcclients/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(/.*)?$ {
set $target_ip $1;
set $rest $2;
proxy_pass http://$target_ip$rest;
proxy_set_header Host $target_ip;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /opengnsys/rest/ous// {
rewrite ^/opengnsys/rest/ous//([0-9]+)/images /opengnsys/rest/ous/$1/images;
rewrite ^/opengnsys/rest/ous//([0-9]+)/labs /opengnsys/rest/ous/$1/labs;
@ -41,6 +31,21 @@ server {
location ~ \.php$ {
return 404;
}
location /mercure/ {
proxy_pass http://ogcore-mercure:3000/;
proxy_read_timeout 24h;
proxy_http_version 1.1;
proxy_set_header Connection "";
# Enable fast reply in SSE
proxy_buffering off;
## Be sure to set USE_FORWARDED_HEADERS=1 to allow the hub to use those headers ##
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_log /var/log/nginx/ogcore-error.log;
access_log /var/log/nginx/ogcore-access.log;
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250325075647 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE client ADD firmware_type VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE client DROP firmware_type');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250326061450 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command ADD parameters TINYINT(1) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command DROP parameters');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250331144522 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository ADD datasize VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository DROP datasize');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250402060324 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image ADD version INT DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image DROP version');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250402081107 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('DROP INDEX UNIQ_IDENTIFIER_IMAGE_REPOSITORY ON image_image_repository');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_IMAGE_REPOSITORY ON image_image_repository (image_id, repository_id)');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250402094550 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository ADD version INT DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository DROP version');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250407063100 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository ADD description VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository DROP description');
}
}

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250407154425 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE INDEX IDX_STATUS ON client (status)');
$this->addSql('CREATE INDEX IDX_UPDATED_AT ON client (updated_at)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP INDEX IDX_STATUS ON client');
$this->addSql('DROP INDEX IDX_UPDATED_AT ON client');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250407154620 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE INDEX IDX_STATUS_UPDATED_AT ON client (status, updated_at)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP INDEX IDX_STATUS_UPDATED_AT ON client');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250408140101 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_repository ADD user VARCHAR(255) DEFAULT NULL, ADD ssh_port VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_repository DROP user, DROP ssh_port');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250409093554 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository ADD name VARCHAR(255) NOT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository DROP name');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250421122715 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task ADD parameters LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:array)\'');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task DROP parameters');
}
}

View File

@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250422092348 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE network_settings ADD pxe_template_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE network_settings ADD CONSTRAINT FK_48869B543BD7665C FOREIGN KEY (pxe_template_id) REFERENCES pxe_template (id)');
$this->addSql('CREATE INDEX IDX_48869B543BD7665C ON network_settings (pxe_template_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE network_settings DROP FOREIGN KEY FK_48869B543BD7665C');
$this->addSql('DROP INDEX IDX_48869B543BD7665C ON network_settings');
$this->addSql('ALTER TABLE network_settings DROP pxe_template_id');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250422140927 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task ADD name VARCHAR(255) NOT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task DROP name');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250423070720 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task DROP datetime');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task ADD datetime DATETIME NOT NULL');
}
}

View File

@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250423071243 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task ADD organizational_unit_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE command_task ADD CONSTRAINT FK_F3D475A8FB84408A FOREIGN KEY (organizational_unit_id) REFERENCES organizational_unit (id)');
$this->addSql('CREATE INDEX IDX_F3D475A8FB84408A ON command_task (organizational_unit_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task DROP FOREIGN KEY FK_F3D475A8FB84408A');
$this->addSql('DROP INDEX IDX_F3D475A8FB84408A ON command_task');
$this->addSql('ALTER TABLE command_task DROP organizational_unit_id');
}
}

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250423092037 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE command_task_schedule (id INT AUTO_INCREMENT NOT NULL, command_task_id INT NOT NULL, uuid CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, recurrence_type VARCHAR(255) NOT NULL, start_time DATETIME NOT NULL, recurrence_details JSON DEFAULT NULL COMMENT \'(DC2Type:json)\', UNIQUE INDEX UNIQ_3BEA77AD17F50A6 (uuid), INDEX IDX_3BEA77A62DC5265 (command_task_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE command_task_schedule ADD CONSTRAINT FK_3BEA77A62DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_schedule DROP FOREIGN KEY FK_3BEA77A62DC5265');
$this->addSql('DROP TABLE command_task_schedule');
}
}

View File

@ -1,45 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250427110103 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE command_task_scripts (id INT AUTO_INCREMENT NOT NULL, command_task_id INT NOT NULL, uuid CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, content VARCHAR(255) NOT NULL, execution_order INT NOT NULL, UNIQUE INDEX UNIQ_E8950142D17F50A6 (uuid), INDEX IDX_E895014262DC5265 (command_task_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE command_task_scripts ADD CONSTRAINT FK_E895014262DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id)');
$this->addSql('ALTER TABLE command_task_command_group DROP FOREIGN KEY FK_C43618BD62DC5265');
$this->addSql('ALTER TABLE command_task_command_group DROP FOREIGN KEY FK_C43618BDC7B800D6');
$this->addSql('ALTER TABLE command_task_command DROP FOREIGN KEY FK_BB417CA862DC5265');
$this->addSql('ALTER TABLE command_task_command DROP FOREIGN KEY FK_BB417CA833E1689A');
$this->addSql('DROP TABLE command_task_command_group');
$this->addSql('DROP TABLE command_task_command');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE command_task_command_group (command_task_id INT NOT NULL, command_group_id INT NOT NULL, INDEX IDX_C43618BD62DC5265 (command_task_id), INDEX IDX_C43618BDC7B800D6 (command_group_id), PRIMARY KEY(command_task_id, command_group_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' ');
$this->addSql('CREATE TABLE command_task_command (command_task_id INT NOT NULL, command_id INT NOT NULL, INDEX IDX_BB417CA862DC5265 (command_task_id), INDEX IDX_BB417CA833E1689A (command_id), PRIMARY KEY(command_task_id, command_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' ');
$this->addSql('ALTER TABLE command_task_command_group ADD CONSTRAINT FK_C43618BD62DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE command_task_command_group ADD CONSTRAINT FK_C43618BDC7B800D6 FOREIGN KEY (command_group_id) REFERENCES command_group (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE command_task_command ADD CONSTRAINT FK_BB417CA862DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE command_task_command ADD CONSTRAINT FK_BB417CA833E1689A FOREIGN KEY (command_id) REFERENCES command (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE command_task_scripts DROP FOREIGN KEY FK_E895014262DC5265');
$this->addSql('DROP TABLE command_task_scripts');
}
}

View File

@ -1,37 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250427125746 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE command_task_script (id INT AUTO_INCREMENT NOT NULL, command_task_id INT NOT NULL, uuid CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, content VARCHAR(255) NOT NULL, execution_order INT NOT NULL, UNIQUE INDEX UNIQ_22BF0112D17F50A6 (uuid), INDEX IDX_22BF011262DC5265 (command_task_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE command_task_script ADD CONSTRAINT FK_22BF011262DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id)');
$this->addSql('ALTER TABLE command_task_scripts DROP FOREIGN KEY FK_E895014262DC5265');
$this->addSql('DROP TABLE command_task_scripts');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE command_task_scripts (id INT AUTO_INCREMENT NOT NULL, command_task_id INT NOT NULL, uuid CHAR(36) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci` COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, updated_by VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, content VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, execution_order INT NOT NULL, INDEX IDX_E895014262DC5265 (command_task_id), UNIQUE INDEX UNIQ_E8950142D17F50A6 (uuid), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' ');
$this->addSql('ALTER TABLE command_task_scripts ADD CONSTRAINT FK_E895014262DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id)');
$this->addSql('ALTER TABLE command_task_script DROP FOREIGN KEY FK_22BF011262DC5265');
$this->addSql('DROP TABLE command_task_script');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250428065311 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_schedule ADD execution_date DATE NOT NULL, ADD execution_time TIME NOT NULL, DROP start_time');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_schedule ADD start_time DATETIME NOT NULL, DROP execution_date, DROP execution_time');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250428065937 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_schedule ADD enabled TINYINT(1) NOT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_schedule DROP enabled');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250428070851 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_schedule CHANGE execution_date execution_date DATE DEFAULT NULL, CHANGE execution_time execution_time TIME DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_schedule CHANGE execution_date execution_date DATE NOT NULL, CHANGE execution_time execution_time TIME NOT NULL');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250429065612 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task ADD last_execution DATETIME DEFAULT NULL, ADD next_execution DATETIME DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task DROP last_execution, DROP next_execution');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250429091808 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task ADD scope VARCHAR(255) NOT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task DROP scope');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250430052434 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_script ADD type VARCHAR(255) NOT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_script DROP type');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250430053742 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_script ADD parameters LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:array)\'');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_script DROP parameters');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250430054513 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_script CHANGE content content VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task_script CHANGE content content VARCHAR(255) NOT NULL');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250430094459 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task DROP status');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE command_task ADD status VARCHAR(255) NOT NULL');
}
}

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250430135412 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE git_image_repository (id INT AUTO_INCREMENT NOT NULL, image_id INT NOT NULL, uuid CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, status VARCHAR(255) NOT NULL, branch VARCHAR(255) NOT NULL, created TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_E6944D5ED17F50A6 (uuid), INDEX IDX_E6944D5E3DA5256D (image_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE git_image_repository ADD CONSTRAINT FK_E6944D5E3DA5256D FOREIGN KEY (image_id) REFERENCES image (id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP FOREIGN KEY FK_E6944D5E3DA5256D');
$this->addSql('DROP TABLE git_image_repository');
}
}

View File

@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250430140218 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository ADD image_repository_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE git_image_repository ADD CONSTRAINT FK_E6944D5E14C736FC FOREIGN KEY (image_repository_id) REFERENCES image_repository (id)');
$this->addSql('CREATE INDEX IDX_E6944D5E14C736FC ON git_image_repository (image_repository_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP FOREIGN KEY FK_E6944D5E14C736FC');
$this->addSql('DROP INDEX IDX_E6944D5E14C736FC ON git_image_repository');
$this->addSql('ALTER TABLE git_image_repository DROP image_repository_id');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250430140326 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository ADD name VARCHAR(255) NOT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP name');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250506094654 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE pxe_template ADD is_default TINYINT(1) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE pxe_template DROP is_default');
}
}

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250506141057 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE client DROP FOREIGN KEY FK_C74404555DA0FB8');
$this->addSql('ALTER TABLE client ADD CONSTRAINT FK_C74404555DA0FB8 FOREIGN KEY (template_id) REFERENCES pxe_template (id) ON DELETE SET NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE client DROP FOREIGN KEY FK_C74404555DA0FB8');
$this->addSql('ALTER TABLE client ADD CONSTRAINT FK_C74404555DA0FB8 FOREIGN KEY (template_id) REFERENCES pxe_template (id)');
}
}

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250508134732 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE `partition` DROP FOREIGN KEY FK_9EB910E43DA5256D');
$this->addSql('ALTER TABLE `partition` ADD CONSTRAINT FK_9EB910E43DA5256D FOREIGN KEY (image_id) REFERENCES image_image_repository (id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE `partition` DROP FOREIGN KEY FK_9EB910E43DA5256D');
$this->addSql('ALTER TABLE `partition` ADD CONSTRAINT FK_9EB910E43DA5256D FOREIGN KEY (image_id) REFERENCES image (id)');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250508152437 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image ADD type VARCHAR(255) NOT NULL, DROP description, DROP comments');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image ADD description VARCHAR(255) DEFAULT NULL, ADD comments VARCHAR(255) DEFAULT NULL, DROP type');
}
}

View File

@ -1,39 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250512071804 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP FOREIGN KEY FK_E6944D5E14C736FC');
$this->addSql('DROP INDEX IDX_E6944D5E14C736FC ON git_image_repository');
$this->addSql('ALTER TABLE git_image_repository ADD tag VARCHAR(255) NOT NULL, CHANGE image_repository_id repository_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE git_image_repository ADD CONSTRAINT FK_E6944D5E50C9D4F7 FOREIGN KEY (repository_id) REFERENCES image_repository (id)');
$this->addSql('CREATE INDEX IDX_E6944D5E50C9D4F7 ON git_image_repository (repository_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP FOREIGN KEY FK_E6944D5E50C9D4F7');
$this->addSql('DROP INDEX IDX_E6944D5E50C9D4F7 ON git_image_repository');
$this->addSql('ALTER TABLE git_image_repository DROP tag, CHANGE repository_id image_repository_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE git_image_repository ADD CONSTRAINT FK_E6944D5E14C736FC FOREIGN KEY (image_repository_id) REFERENCES image_repository (id)');
$this->addSql('CREATE INDEX IDX_E6944D5E14C736FC ON git_image_repository (image_repository_id)');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250512075927 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository CHANGE branch branch VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository CHANGE branch branch VARCHAR(255) NOT NULL');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250512081045 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository ADD version INT DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP version');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250513050921 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository ADD description VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP description');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250513055057 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository ADD partition_info VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image_image_repository DROP partition_info');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250514051344 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE client ADD token VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE client DROP token');
}
}

View File

@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250514101117 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_NAME ON command (name)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP INDEX UNIQ_IDENTIFIER_NAME ON command');
}
}

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250604084222 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE `partition` DROP FOREIGN KEY FK_9EB910E43DA5256D');
$this->addSql('ALTER TABLE `partition` ADD CONSTRAINT FK_9EB910E43DA5256D FOREIGN KEY (image_id) REFERENCES image_image_repository (id) ON DELETE SET NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE `partition` DROP FOREIGN KEY FK_9EB910E43DA5256D');
$this->addSql('ALTER TABLE `partition` ADD CONSTRAINT FK_9EB910E43DA5256D FOREIGN KEY (image_id) REFERENCES image_image_repository (id)');
}
}

View File

@ -1,37 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250618114502 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE git_repository (id INT AUTO_INCREMENT NOT NULL, uuid CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, description VARCHAR(255) DEFAULT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_C2B3204AD17F50A6 (uuid), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE git_image_repository ADD git_repository_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE git_image_repository ADD CONSTRAINT FK_E6944D5EDCA00B70 FOREIGN KEY (git_repository_id) REFERENCES git_repository (id)');
$this->addSql('CREATE INDEX IDX_E6944D5EDCA00B70 ON git_image_repository (git_repository_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP FOREIGN KEY FK_E6944D5EDCA00B70');
$this->addSql('DROP TABLE git_repository');
$this->addSql('DROP INDEX IDX_E6944D5EDCA00B70 ON git_image_repository');
$this->addSql('ALTER TABLE git_image_repository DROP git_repository_id');
}
}

View File

@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250618115400 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_repository ADD repository_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE git_repository ADD CONSTRAINT FK_C2B3204A50C9D4F7 FOREIGN KEY (repository_id) REFERENCES image_repository (id)');
$this->addSql('CREATE INDEX IDX_C2B3204A50C9D4F7 ON git_repository (repository_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_repository DROP FOREIGN KEY FK_C2B3204A50C9D4F7');
$this->addSql('DROP INDEX IDX_C2B3204A50C9D4F7 ON git_repository');
$this->addSql('ALTER TABLE git_repository DROP repository_id');
}
}

View File

@ -1,37 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250626145458 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP FOREIGN KEY FK_E6944D5EDCA00B70');
$this->addSql('ALTER TABLE git_image_repository DROP FOREIGN KEY FK_E6944D5E3DA5256D');
$this->addSql('ALTER TABLE git_image_repository DROP FOREIGN KEY FK_E6944D5E50C9D4F7');
$this->addSql('DROP TABLE git_image_repository');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE git_image_repository (id INT AUTO_INCREMENT NOT NULL, image_id INT NOT NULL, repository_id INT DEFAULT NULL, git_repository_id INT DEFAULT NULL, uuid CHAR(36) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci` COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, updated_by VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, status VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, branch VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, created TINYINT(1) NOT NULL, name VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, tag VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, version INT DEFAULT NULL, description VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, UNIQUE INDEX UNIQ_E6944D5ED17F50A6 (uuid), INDEX IDX_E6944D5E3DA5256D (image_id), INDEX IDX_E6944D5E50C9D4F7 (repository_id), INDEX IDX_E6944D5EDCA00B70 (git_repository_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' ');
$this->addSql('ALTER TABLE git_image_repository ADD CONSTRAINT FK_E6944D5EDCA00B70 FOREIGN KEY (git_repository_id) REFERENCES git_repository (id)');
$this->addSql('ALTER TABLE git_image_repository ADD CONSTRAINT FK_E6944D5E3DA5256D FOREIGN KEY (image_id) REFERENCES image (id)');
$this->addSql('ALTER TABLE git_image_repository ADD CONSTRAINT FK_E6944D5E50C9D4F7 FOREIGN KEY (repository_id) REFERENCES image_repository (id)');
}
}

View File

View File

@ -1,100 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Command;
use App\Entity\Client;
use App\Entity\Trace;
use App\Model\ClientStatus;
use App\Model\TraceStatus;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Mercure\HubInterface;
use Symfony\Component\Mercure\Update;
#[AsCommand(name: 'opengnsys:check-client-availability', description: 'Check client availability')]
class CheckClientAvailability extends Command
{
const int THRESHOLD_MINUTES = 1;
public function __construct(
private readonly HubInterface $hub,
private readonly EntityManagerInterface $entityManager
)
{
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$threshold = (new \DateTime())->modify(' - '.self::THRESHOLD_MINUTES . ' minutes');
$startQueryTime = microtime(true);
$validStatuses = [ClientStatus::OG_LIVE, ClientStatus::WINDOWS, ClientStatus::LINUX, ClientStatus::MACOS, ClientStatus::INITIALIZING, ClientStatus::LINUX_SESSION, ClientStatus::WINDOWS_SESSION];
$query = $this->entityManager->createQuery(
'UPDATE App\Entity\Client c
SET c.status = :status
WHERE c.status IN (:currentStatuses)
AND c.updatedAt < :threshold'
);
$query->setParameter('status', ClientStatus::DISCONNECTED);
$query->setParameter('currentStatuses', $validStatuses);
$query->setParameter('threshold', $threshold);
$updatedCount = $query->execute();
$queryTime = microtime(true) - $startQueryTime;
$startMercureTime = microtime(true);
$clients = $this->entityManager->createQueryBuilder()
->select('c')
->from(Client::class, 'c')
->where('c.status = :status')
->andWhere('c.updatedAt < :threshold')
->setParameter('status', ClientStatus::DISCONNECTED)
->setParameter('threshold', $threshold)
->getQuery()
->getResult();
$this->dispatchMercureEvent($clients);
$mercureTime = microtime(true) - $startMercureTime;
$io->success("Updated $updatedCount clients to DISCONNECTED status.");
$io->note("Query time: " . round($queryTime, 3) . "s");
$io->note("Mercure dispatch time: " . round($mercureTime, 3) . "s");
return Command::SUCCESS;
}
private function dispatchMercureEvent(array $clients, int $chunkSize = 10000): void
{
$chunks = array_chunk($clients, $chunkSize);
foreach ($chunks as $chunk) {
$data = [];
foreach ($chunk as $client) {
$data[] = [
'@id' => '/clients/' . $client->getUuid(),
'status' => $client->getStatus(),
];
}
$update = new Update(
'clients',
json_encode($data)
);
$this->hub->publish($update);
}
}
}

View File

@ -20,8 +20,6 @@ class LoadDefaultUserAdminCommand extends Command
CONST string PLAIN_PASSWORD = '12345678';
const string USERNAME = 'ogadmin';
const string DEFAULT_GROUPS_VIEW = 'card';
public function __construct(
private readonly EntityManagerInterface $entityManager
)
@ -39,7 +37,6 @@ class LoadDefaultUserAdminCommand extends Command
$user = new User();
$user->setUsername(self::USERNAME);
$user->setGroupsView(self::DEFAULT_GROUPS_VIEW);
$user->setRoles([UserGroupPermissions::ROLE_SUPER_ADMIN]);
$user->setPassword($hash);

View File

@ -1,89 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Command;
use App\Controller\OgAgent\DeployImageAction;
use App\Controller\OgAgent\RunScriptAction;
use App\Dto\Input\CommandExecuteInput;
use App\Dto\Input\DeployImageInput;
use App\Dto\Output\ClientOutput;
use App\Entity\CommandTask;
use App\Model\ClientStatus;
use App\Repository\CommandTaskRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
#[AsCommand(name: 'opengnsys:run-scheduled-command-tasks', description: 'Run scheduled command tasks')]
class RunScheduledCommandTasksCommand extends Command
{
public function __construct(
private readonly CommandTaskRepository $commandTaskRepository,
private readonly EntityManagerInterface $entityManager,
private readonly RunScriptAction $runScriptAction,
private readonly DeployImageAction $deployImageAction,
)
{
parent::__construct();
}
/**
* @throws \Exception
* @throws TransportExceptionInterface
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$now = new \DateTimeImmutable('now +2 hours');
$now->setTimezone(new \DateTimeZone('Europe/Madrid'));
$nowMinute = $now->format('Y-m-d H:i');
$tasks = $this->commandTaskRepository->findAll();
foreach ($tasks as $task) {
/** @var CommandTask $task */
$nextExecution = $task->getNextExecution();
if (!$nextExecution) {
continue;
}
$taskMinute = $nextExecution->format('Y-m-d H:i');
if ($taskMinute === $nowMinute) {
$output->writeln("Ejecutando tarea: " . $task->getName());
$scripts = $task->getCommandTaskScripts()->toArray();
usort($scripts, fn($a, $b) => $a->getExecutionOrder() <=> $b->getExecutionOrder());
foreach ($scripts as $script) {
$output->writeln(" - Ejecutando script de tipo {$script->getType()} con orden {$script->getExecutionOrder()}");
if ($script->getType() === 'run-script') {
$input = new CommandExecuteInput();
foreach ($task->getOrganizationalUnit()?->getClients() as $client) {
if ($client->getStatus() !== ClientStatus::OG_LIVE) {
continue;
}
$input->clients[] = new ClientOutput($client);
}
$input->script = $script->getContent();
$this->runScriptAction->__invoke($input);
}
}
$task->setLastExecution(new \DateTime());
$task->setNextExecution($task->calculateNextExecutionDate());
$this->entityManager->persist($task);
}
}
$this->entityManager->flush();
return Command::SUCCESS;
}
}

View File

@ -4,7 +4,9 @@ declare(strict_types=1);
namespace App\Command;
use App\Entity\Client;
use App\Entity\Trace;
use App\Model\ClientStatus;
use App\Model\TraceStatus;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
@ -12,38 +14,31 @@ use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Mercure\HubInterface;
use Symfony\Component\Mercure\Update;
#[AsCommand(name: 'opengnsys:execute-pending-traces', description: 'Execute pending traces')]
class ExecutePendingTracesCommand extends Command
#[AsCommand(name: 'opengnsys:test', description: 'Hello PhpStorm')]
class TestCommand extends Command
{
public function __construct(
private readonly HubInterface $hub,
private readonly EntityManagerInterface $entityManager
) {
)
{
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$startTime = microtime(true);
$trace = $this->entityManager->getRepository(Trace::class)->find(7236);
$traces = $this->entityManager->getRepository(Trace::class)
->findBy(['status' => TraceStatus::PENDING]);
$count = count($traces);
$io->info("Found $count pending traces");
foreach ($traces as $trace) {
$trace->setStatus(TraceStatus::IN_PROGRESS);
$this->entityManager->persist($trace);
}
$trace->setStatus(TraceStatus::SUCCESS);
$trace->setProgress(1000);
$this->entityManager->persist($trace);
$this->entityManager->flush();
$executionTime = microtime(true) - $startTime;
$io->success("Updated $count traces to IN_PROGRESS status");
$io->note("Execution time: " . round($executionTime, 3) . "s");
return Command::SUCCESS;
}
}
}

View File

@ -1,54 +0,0 @@
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
class AuthValidatorController extends AbstractController
{
private JWTTokenManagerInterface $jwtManager;
public function __construct(JWTTokenManagerInterface $jwtManager)
{
$this->jwtManager = $jwtManager;
}
#[Route('/validate', name: 'auth_validate', methods: ['POST'])]
public function validate(Request $request): Response
{
$sslClientVerify = $request->headers->get('SSL_CLIENT_VERIFY');
$clientCertOk = $sslClientVerify === 'SUCCESS';
$authHeader = $request->headers->get('Authorization');
$hasValidJwt = $this->validateJwtToken($authHeader);
if ($clientCertOk || $hasValidJwt) {
return new Response('Authorized', Response::HTTP_OK);
}
return new Response('Unauthorized', Response::HTTP_UNAUTHORIZED);
}
private function validateJwtToken(?string $authHeader): bool
{
if (!$authHeader || !str_starts_with($authHeader, 'Bearer ')) {
return false;
}
$token = substr($authHeader, 7);
try {
$payload = $this->jwtManager->parse($token);
return true;
} catch (\Exception $e) {
return false;
}
}
}

View File

@ -1,35 +0,0 @@
<?php
namespace App\Controller;
use App\Dto\Input\CancelMultipleTracesInput;
use App\Entity\Trace;
use App\Model\TraceStatus;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
class CancelMultipleTracesAction extends AbstractController
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
)
{
}
public function __invoke(CancelMultipleTracesInput $input): JsonResponse
{
foreach ($input->traces as $trace) {
/** @var Trace $trace */
$trace = $trace->getEntity();
$trace->setStatus(TraceStatus::CANCELLED);
$this->entityManager->persist($trace);
}
$this->entityManager->flush();
return new JsonResponse(data: 'Traces cancelled successfully', status: Response::HTTP_OK);
}
}

View File

@ -2,9 +2,7 @@
namespace App\Controller;
use App\Controller\OgBoot\PxeBootFile\PostAction;
use App\Dto\Input\ChangeOrganizationalUnitInput;
use App\Dto\Output\ClientOutput;
use App\Entity\Client;
use App\Repository\ClientRepository;
use Doctrine\ORM\EntityManagerInterface;
@ -12,44 +10,29 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class ChangeOrganizationalUnitAction extends AbstractController
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private PostAction $postAction,
private readonly ClientRepository $clientRepository,
private readonly EntityManagerInterface $entityManager
)
{
}
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(ChangeOrganizationalUnitInput $input): JsonResponse
{
foreach ($input->clients as $client) {
/** @var Client $clientEntity */
$clientEntity = $client->getEntity();
/** @var Client $client */
$clientEntity = $this->clientRepository->find($client->getEntity()->getId());
if (!$clientEntity) {
throw new NotFoundHttpException('Client not found');
}
$organizationalUnit = $input->organizationalUnit->getEntity();
$clientEntity->setOrganizationalUnit($organizationalUnit);
$this->entityManager->persist($clientEntity);
$template = $clientEntity->getTemplate() ?? $clientEntity->getOrganizationalUnit()->getNetworkSettings()?->getTemplate();
if (!$template) {
throw new BadRequestHttpException('No template found for client');
}
$this->postAction->__invoke($clientEntity, $template);
}
$this->entityManager->flush();

View File

@ -1,98 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use ApiPlatform\Validator\ValidatorInterface;
use App\Dto\Input\DeployGitImageInput;
use App\Entity\Command;
use App\Entity\Image;
use App\Model\ClientStatus;
use App\Entity\ImageImageRepository;
use App\Entity\OrganizationalUnit;
use App\Entity\Partition;
use App\Model\CommandTypes;
use App\Model\DeployMethodTypes;
use App\Model\TraceStatus;
use App\Service\Trace\CreateService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class DeployGitImageAction extends AbstractController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly CreateService $createService,
protected readonly ValidatorInterface $validator,
public readonly \App\Controller\OgAgent\DeployGitImageAction $deployGitImageOgAgentAction,
) {
}
/**
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
* @throws ServerExceptionInterface
*/
public function __invoke(DeployGitImageInput $input): JsonResponse
{
$this->validator->validate($input);
$clientJobs = $this->handleGitDeployment($input);
return new JsonResponse(data: $clientJobs, status: Response::HTTP_OK);
}
private function handleGitDeployment(DeployGitImageInput $input): array
{
$clientJobs = [];
foreach ($input->clients as $client) {
$inputData = $this->createInputData($input, $client->getEntity());
$jobId = $this->processDeployment($client->getEntity(), $input, $inputData, DeployMethodTypes::GIT);
if ($jobId) {
$clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId;
}
}
return $clientJobs;
}
private function processDeployment($client, DeployGitImageInput $input, array $inputData, string $deployType): ?string
{
$agentJobId = $this->deployGitImageOgAgentAction->__invoke($input, $client);
if (!$agentJobId) {
if ($input->queue) {
$this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::PENDING, null, $inputData);
}
return null;
}
$this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
return $agentJobId;
}
private function createInputData(DeployGitImageInput $input, $client): array
{
return [
'method' => $input->method,
'client' => $client->getUuid(),
'hexsha' => $input->hexsha,
'repositoryName' => $input->repositoryName,
'branch' => $input->branch,
'numDisk' => (string) $input->diskNumber,
'numPartition' => (string) $input->partitionNumber,
'type' => $input->type,
];
}
}

View File

@ -8,7 +8,6 @@ use ApiPlatform\Validator\ValidatorInterface;
use App\Dto\Input\DeployImageInput;
use App\Entity\Command;
use App\Entity\Image;
use App\Model\ClientStatus;
use App\Entity\ImageImageRepository;
use App\Entity\OrganizationalUnit;
use App\Entity\Partition;
@ -32,10 +31,11 @@ class DeployImageAction extends AbstractController
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly ValidatorInterface $validator,
protected readonly ValidatorInterface $validator,
public readonly \App\Controller\OgAgent\DeployImageAction $deployImageOgAgentAction,
public readonly \App\Controller\OgRepository\Image\DeployImageAction $deployImageOgRepositoryAction,
) {
)
{
}
/**
@ -47,149 +47,89 @@ class DeployImageAction extends AbstractController
{
$this->validator->validate($input);
$clientJobs = [];
if ($input->type === 'monolithic') {
$clientJobs = $this->handleMonolithicDeployment($input, $image);
}
return new JsonResponse(data: $clientJobs, status: Response::HTTP_OK);
}
private function handleMonolithicDeployment(DeployImageInput $input, ImageImageRepository $image): array
{
$clientJobs = [];
switch ($input->method) {
switch ($input->method){
case DeployMethodTypes::UNICAST:
case DeployMethodTypes::UNICAST_DIRECT:
$clientJobs = $this->handleUnicastDeployment($input, $image);
break;
foreach ($input->clients as $client) {
$inputData = [
'method' => $input->method,
'client' => $client->getEntity()->getUuid(),
'image' => $image->getUuid(),
'numDisk' => (string) $input->diskNumber,
'numPartition' => (string) $input->partitionNumber,
];
$agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client->getEntity(), DeployMethodTypes::UNICAST);
if (!$agentJobId){
continue;
}
$this->createService->__invoke($client->getEntity(), CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
}
break;
case DeployMethodTypes::MULTICAST_UFTP:
case DeployMethodTypes::MULTICAST_UFTP_DIRECT:
case DeployMethodTypes::MULTICAST_UDPCAST:
case DeployMethodTypes::MULTICAST_UDPCAST_DIRECT:
$clientJobs = $this->handleMulticastDeployment($input, $image);
break;
case DeployMethodTypes::TORRENT:
$clientJobs = $this->handleTorrentDeployment($input, $image);
break;
}
foreach ($input->clients as $client) {
$inputData = [
'method' => $input->method,
'client' => $client->getEntity()->getUuid(),
'image' => $image->getUuid(),
'mcastIp' => $input->mcastIp,
'mcastPort' => $input->mcastPort,
'mcastSpeed' => $input->mcastSpeed,
'mcastMode' => $input->mcastMode,
'numDisk' => (string) $input->diskNumber,
'numPartition' => (string) $input->partitionNumber,
];
return $clientJobs;
}
try {
$this->deployImageOgRepositoryAction->__invoke($input, $image, $client->getEntity(), $this->httpClient);
} catch (\Exception $e) {
continue;
}
private function handleUnicastDeployment(DeployImageInput $input, ImageImageRepository $image): array
{
$clientJobs = [];
$agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client->getEntity(), DeployMethodTypes::MULTICAST);
if (!$agentJobId){
continue;
}
foreach ($input->clients as $client) {
$inputData = $this->createInputData($input, $image, $client->getEntity());
$jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::UNICAST);
if ($jobId) {
$clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId;
}
}
return $clientJobs;
}
private function handleMulticastDeployment(DeployImageInput $input, ImageImageRepository $image): array
{
$clientJobs = [];
foreach ($input->clients as $client) {
$inputData = $this->createMulticastInputData($input, $image, $client->getEntity());
try {
$this->deployImageOgRepositoryAction->__invoke($input, $image, $client->getEntity());
} catch (\Exception $e) {
continue;
}
$jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::MULTICAST);
if ($jobId) {
$clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId;
}
}
return $clientJobs;
}
private function handleTorrentDeployment(DeployImageInput $input, ImageImageRepository $image): array
{
$clientJobs = [];
foreach ($input->clients as $client) {
$inputData = $this->createTorrentInputData($input, $image, $client->getEntity());
try {
$response = $this->deployImageOgRepositoryAction->__invoke($input, $image, $client->getEntity(), $this->httpClient);
if (is_array($response) && isset($response['code']) && $response['code'] === 500) {
throw new \Exception('Error del servidor OgRepository: ' . ($response['error'] ?? 'Error desconocido') . ' - ' . ($response['details'] ?? ''));
$this->createService->__invoke($client->getEntity(), CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
}
} catch (\Exception $e) {
throw $e;
}
break;
$jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::TORRENT);
if ($jobId) {
$clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId;
}
case DeployMethodTypes::TORRENT:
foreach ($input->clients as $client) {
$inputData = [
'method' => $input->method,
'client' => $client->getEntity()->getUuid(),
'image' => $image->getUuid(),
'p2pMode' => $input->p2pMode,
'p2pTime' => $input->p2pTime,
'numDisk' => (string) $input->diskNumber,
'numPartition' => (string) $input->partitionNumber,
];
try {
$this->deployImageOgRepositoryAction->__invoke($input, $image, $client->getEntity(), $this->httpClient);
} catch (\Exception $e) {
continue;
}
$agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client->getEntity(), DeployMethodTypes::TORRENT);
if (!$agentJobId){
continue;
}
$this->createService->__invoke($client->getEntity(), CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
}
break;
}
return $clientJobs;
}
private function processDeployment($client, DeployImageInput $input, ImageImageRepository $image, array $inputData, string $deployType): ?string
{
$agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client, $deployType);
if (!$agentJobId) {
if ($input->queue) {
$this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::PENDING, null, $inputData);
}
return null;
}
$this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
return $agentJobId;
}
private function createInputData(DeployImageInput $input, ImageImageRepository $image, $client): array
{
return [
'method' => $input->method,
'client' => $client->getUuid(),
'image' => $image->getUuid(),
'imageName' => $image->getName(),
'numDisk' => (string) $input->diskNumber,
'numPartition' => (string) $input->partitionNumber,
'type' => $input->type,
];
}
private function createMulticastInputData(DeployImageInput $input, ImageImageRepository $image, $client): array
{
return array_merge($this->createInputData($input, $image, $client), [
'mcastIp' => $input->mcastIp,
'mcastPort' => $input->mcastPort,
'mcastSpeed' => $input->mcastSpeed,
'mcastMode' => $input->mcastMode,
]);
}
private function createTorrentInputData(DeployImageInput $input, ImageImageRepository $image, $client): array
{
return array_merge($this->createInputData($input, $image, $client), [
'p2pMode' => $input->p2pMode,
'p2pTime' => $input->p2pTime,
]);
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

View File

@ -1,87 +0,0 @@
<?php
namespace App\Controller\OgAgent;
use App\Controller\OgRepository\Git\CreateRepositoryAction;
use App\Controller\OgRepository\Git\SshKeyAction;
use App\Service\CreatePartitionService;
use App\Service\Trace\CreateService;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
#[AsController]
abstract class AbstractOgAgentController extends AbstractController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreatePartitionService $createPartitionService,
protected readonly LoggerInterface $logger,
protected readonly CreateService $createService,
protected readonly CreateRepositoryAction $createRepositoryAction,
protected readonly SshKeyAction $sshKeyAction,
#[Autowire(env: 'SSL_ENABLED')]
private readonly string $sslEnabled,
)
{
}
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function createRequest(string $method, string $url, array $params = [], string $token = null): array
{
$params = array_merge($params, [
'headers' => [
'accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => $token,
],
'verify_peer' => false,
'verify_host' => false,
'timeout' => 10
]);
if ($this->sslEnabled === 'true') {
$params['verify_peer'] = true;
$params['verify_host'] = false;
$params['cafile'] = '/opt/opengnsys/ogcore/etc/certificates/ca.crt';
$params['local_cert'] = '/opt/opengnsys/ogcore/etc/certificates/ogcore.crt';
$params['local_pk'] = '/opt/opengnsys/ogcore/etc/certificates/ogcore.key';
}
try {
$response = $this->httpClient->request($method, $url, $params);
return json_decode($response->getContent(), true);
} catch (ClientExceptionInterface | ServerExceptionInterface $e) {
$this->logger->error(sprintf('Client/Server error in request to %s: %s', $url, $e->getMessage()));
return [
'code' => Response::HTTP_INTERNAL_SERVER_ERROR,
'error' => 'Client/Server error',
'details' => $e->getMessage(),
];
} catch (TransportExceptionInterface $e) {
$this->logger->error(sprintf('Transport error in request to %s: %s', $url, $e->getMessage()));
return [
'code' => Response::HTTP_INTERNAL_SERVER_ERROR,
'error' => 'Transport error',
'details' => $e->getMessage(),
];
}
}
}

View File

@ -4,14 +4,10 @@ declare(strict_types=1);
namespace App\Controller\OgAgent;
use App\Controller\OgRepository\Git\CreateRepositoryAction;
use App\Entity\Client;
use App\Entity\Command;
use App\Entity\GitRepository;
use App\Entity\Image;
use App\Entity\ImageImageRepository;
use App\Entity\ImageRepository;
use App\Entity\Partition;
use App\Entity\Trace;
use App\Model\ClientStatus;
use App\Model\CommandTypes;
@ -25,7 +21,6 @@ use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
@ -34,57 +29,15 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class CreateImageAction extends AbstractOgAgentController
class CreateImageAction extends AbstractController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(bool $queue, Image $image, ?Partition $partition = null, ?Client $client = null, ?string $gitRepositoryName = null): JsonResponse
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
{
$client = $client ?? $image->getClient();
if (!$client->getIp()) {
throw new BadRequestHttpException('IP is required');
}
$partitionInfo = [];
if ($partition) {
$partitionInfo["numPartition"] = $partition->getPartitionNumber();
$partitionInfo["numDisk"] = $partition->getDiskNumber();
$partitionInfo["partitionCode"] = $partition->getPartitionCode();
$partitionInfo["filesystem"] = $partition->getFilesystem();
$partitionInfo["osName"] = $partition->getOperativeSystem()?->getName();
$image->setPartitionInfo(json_encode($partitionInfo));
} else {
$partitionInfo = json_decode($image->getPartitionInfo(), true);
}
if ($image->getType() === 'monolithic') {
$repository = $image->getClient()->getRepository();
$latestImageRepo = $this->entityManager->getRepository(ImageImageRepository::class)->findLatestVersionByImageAndRepository($image, $repository);
$imageImageRepository = new ImageImageRepository();
$imageImageRepository->setName($image->getName().'_v'.($latestImageRepo ? $latestImageRepo->getVersion() + 1 : 1));
$imageImageRepository->setImage($image);
$imageImageRepository->setRepository($repository);
$imageImageRepository->setStatus(ImageStatus::IN_PROGRESS);
$imageImageRepository->setVersion($latestImageRepo ? $latestImageRepo->getVersion() + 1 : 1);
$imageImageRepository->setPartitionInfo(json_encode($partitionInfo));
$this->entityManager->persist($imageImageRepository);
return $this->createMonolithicImage($imageImageRepository, $partitionInfo, $image, $repository, $client, $queue);
} else {
$repository = $image->getClient()->getRepository();
// Para imágenes Git, no necesitamos crear entidades en la base de datos
// ya que los repositorios Git son datos externos
return $this->createGitImage($image, $partitionInfo, $repository, $queue, $gitRepositoryName);
}
}
/**
@ -93,30 +46,29 @@ class CreateImageAction extends AbstractOgAgentController
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function createMonolithicImage(
ImageImageRepository $imageImageRepository,
array $partitionInfo,
Image $image,
ImageRepository $repository,
?Client $client = null,
bool $queue = false
): JsonResponse
public function __invoke(Image $image): JsonResponse
{
if (!isset($partitionInfo['numDisk'], $partitionInfo['numPartition'], $partitionInfo['partitionCode'], $partitionInfo['filesystem'])) {
throw new BadRequestHttpException('Missing required partition information');
if (!$image->getClient()->getIp()) {
throw new ValidatorException('IP is required');
}
$client = $client ?? $image->getClient();
if (!$client->getIp() || !$client->getToken()) {
throw new BadRequestHttpException('Client IP or token is missing');
}
$partitionInfo = json_decode($image->getPartitionInfo(), true);
$repository = $image->getClient()->getRepository();
$imageImageRepository = new ImageImageRepository();
$imageImageRepository->setImage($image);
$imageImageRepository->setRepository($repository);
$imageImageRepository->setStatus(ImageStatus::IN_PROGRESS);
$this->entityManager->persist($imageImageRepository);
$data = [
'dsk' => (string) $partitionInfo['numDisk'],
'par' => (string) $partitionInfo['numPartition'],
'cpt' => null,
'idi' => $imageImageRepository->getUuid(),
'nci' => $image->getName().'_v'.$imageImageRepository->getVersion(),
'nci' => $image->getName(),
'ipr' => $repository->getIp(),
'nfn' => 'CrearImagen',
'ids' => '0'
@ -133,219 +85,38 @@ class CreateImageAction extends AbstractOgAgentController
$data['cpt'] = dechex($partitionTypeCode);
} else {
throw new BadRequestHttpException("Invalid partition code: {$partitionCode}");
throw new Exception("El tipo de partición '$partitionCode' no se encontró en la lista.");
}
$this->logger->info('Creating image', ['image' => $image->getId()]);
try {
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/CrearImagen',
params: [
'json' => $data,
$this->logger->info('Creating image', ['image' => $image->getId()]);
$response = $this->httpClient->request('POST', 'https://'.$image->getClient()->getIp().':8000/CloningEngine/CrearImagen', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
token: $client->getToken(),
);
$this->logger->info('Creating image', ['image' => $imageImageRepository->getName(), 'repository' => $repository->getIp()]);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
if ($queue) {
$inputData = [
'method' => 'CrearImagen',
'type' => 'monolithic',
'client' => $client->getUuid(),
'image' => $image->getUuid(),
'partitionCode' => $partitionInfo['partitionCode'],
'partitionType' => $partitionInfo['filesystem'],
'repository' => $repository->getIp(),
'name' => $image->getName().'_v'.$imageImageRepository->getVersion(),
];
$this->createService->__invoke($client, CommandTypes::CREATE_IMAGE, TraceStatus::PENDING, null, $inputData);
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
throw new BadRequestHttpException('Error creating image: ' . ($response['message'] ?? 'Unknown error'));
}
if (!isset($response['job_id'])) {
throw new BadRequestHttpException('No job ID received from server');
}
$jobId = $response['job_id'];
try {
$client->setStatus(ClientStatus::BUSY);
$imageImageRepository->setStatus(ImageStatus::IN_PROGRESS);
$this->entityManager->persist($client);
$this->entityManager->persist($imageImageRepository);
$this->entityManager->flush();
$inputData = [
'method' => 'CrearImagen',
'type' => 'monolithic',
'client' => $client->getUuid(),
'image' => $image->getUuid(),
'partitionCode' => $partitionInfo['partitionCode'],
'partitionType' => $partitionInfo['filesystem'],
'repository' => $repository->getIp(),
'name' => $image->getName().'_v'.$imageImageRepository->getVersion(),
];
$this->createService->__invoke(
$image->getClient(),
CommandTypes::CREATE_IMAGE,
TraceStatus::IN_PROGRESS,
$jobId,
$inputData
);
return new JsonResponse(data: ['/clients/' . $client->getUuid() => $jobId], status: Response::HTTP_OK);
} catch (Exception $e) {
$client->setStatus(ClientStatus::OG_LIVE);
$this->entityManager->persist($client);
$this->entityManager->flush();
throw $e;
}
} catch (Exception $e) {
$this->logger->error('Error in monolithic image creation process', [
'repository' => $repository->getId(),
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
'json' => $data,
]);
} catch (TransportExceptionInterface $e) {
$this->logger->error('Error creating image', ['image' => $image->getId(), 'error' => $e->getMessage()]);
return new JsonResponse(
data: ['error' => $e->getMessage()],
status: Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
public function createGitImage(
Image $image,
array $partitionInfo,
ImageRepository $repository,
bool $queue = false,
?string $gitRepositoryName = null
): JsonResponse
{
if (!isset($partitionInfo['numDisk'], $partitionInfo['numPartition'], $partitionInfo['partitionCode'], $partitionInfo['filesystem'])) {
throw new BadRequestHttpException('Missing required partition information');
}
$jobId = json_decode($response->getContent(), true)['job_id'];
$client = $image->getClient();
if (!$client->getIp() || !$client->getToken()) {
throw new BadRequestHttpException('Client IP or token is missing');
}
$client->setStatus(ClientStatus::BUSY);
$this->entityManager->persist($client);
$this->entityManager->flush();
try {
$data = [
'dsk' => (string) $partitionInfo['numDisk'],
'par' => (string) $partitionInfo['numPartition'],
'cpt' => null,
'idi' => $gitRepositoryName ?: $image->getUuid(),
'nci' => $gitRepositoryName ?: $image->getName(),
'ipr' => $repository->getIp(),
'nfn' => 'CrearImagenGit',
'tag' => '',
'ids' => '0'
];
$this->createService->__invoke($image->getClient(), CommandTypes::CREATE_IMAGE, TraceStatus::IN_PROGRESS, $jobId, []);
$partitionTypes = PartitionTypes::getPartitionTypes();
$partitionCode = $partitionInfo['partitionCode'];
$cptKey = array_search($partitionCode, array_column($partitionTypes, 'name'), true);
if ($cptKey !== false) {
$keys = array_keys($partitionTypes);
$partitionTypeCode = $keys[$cptKey];
$data['cpt'] = dechex($partitionTypeCode);
} else {
throw new BadRequestHttpException("Invalid partition code: {$partitionCode}");
}
//$this->sshKeyAction->__invoke($repository, $client);
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/CrearImagenGit',
params: [
'json' => $data,
],
token: $client->getToken(),
);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
if ($queue) {
$inputData = [
'method' => 'CrearImagenGit',
'type' => 'git',
'client' => $client->getUuid(),
'image' => $image->getUuid(),
'partitionCode' => $partitionInfo['partitionCode'],
'partitionType' => $partitionInfo['filesystem'],
'repository' => $repository->getIp(),
'name' => $image->getName(),
];
$this->createService->__invoke($client, CommandTypes::CREATE_IMAGE_GIT, TraceStatus::PENDING, null, $inputData);
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
throw new BadRequestHttpException('Error creating image: ' . ($response['message'] ?? 'Unknown error'));
}
if (!isset($response['job_id'])) {
throw new BadRequestHttpException('No job ID received from server');
}
$jobId = $response['job_id'];
try {
$client->setStatus(ClientStatus::BUSY);
$this->entityManager->persist($client);
$this->entityManager->flush();
$inputData = [
'method' => 'CrearImagenGit',
'type' => 'git',
'client' => $client->getUuid(),
'image' => $image->getUuid(),
'partitionCode' => $partitionInfo['partitionCode'],
'partitionType' => $partitionInfo['filesystem'],
'repository' => $repository->getIp(),
'name' => $image->getName(),
];
$this->createService->__invoke(
$image->getClient(),
CommandTypes::CREATE_IMAGE_GIT,
TraceStatus::IN_PROGRESS,
$jobId,
$inputData
);
return new JsonResponse(data: ['/clients/' . $client->getUuid() => $jobId], status: Response::HTTP_OK);
} catch (Exception $e) {
$client->setStatus(ClientStatus::OG_LIVE);
$this->entityManager->persist($client);
$this->entityManager->flush();
throw $e;
}
} catch (Exception $e) {
$this->logger->error('Error in git image creation process', [
'repository' => $repository->getId(),
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return new JsonResponse(
data: ['error' => $e->getMessage()],
status: Response::HTTP_INTERNAL_SERVER_ERROR
);
}
return new JsonResponse(data: $image, status: Response::HTTP_OK);
}
}

View File

@ -1,91 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Controller\OgAgent;
use App\Dto\Input\DeployGitImageInput;
use App\Entity\Client;
use App\Entity\Image;
use App\Model\ClientStatus;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class DeployGitImageAction extends AbstractOgAgentController
{
/**
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
*/
public function __invoke(DeployGitImageInput $input, Client $client)
{
if (!$client->getIp()) {
throw new BadRequestHttpException('IP is required');
}
if (!$input->hexsha && !$input->tag) {
throw new BadRequestHttpException('Either hexsha or tag is required for Git image deployment');
}
if (!$input->repositoryName) {
throw new BadRequestHttpException('Repository name is required for Git image deployment');
}
if (!$input->branch) {
throw new BadRequestHttpException('Branch is required for Git image deployment');
}
$repository = $client->getRepository();
$data = [
'dsk' => (string) $input->diskNumber,
'par' => (string) $input->partitionNumber,
'ifs' => "1",
'idi' => 1,
'nci' => $input->repositoryName,
'ipr' => $repository->getIp(),
'nfn' => 'RestaurarImagenGit',
'ptc' => 'git',
'ids' => '0',
'ref' => $input->hexsha ?? $input->tag
];
$url = 'https://'.$client->getIp().':8000/opengnsys/RestaurarImagenGit';
$response = $this->createRequest(
method: 'POST',
url: $url,
params: [
'json' => $data,
],
token: $client->getToken(),
);
$this->logger->info('Deploying Git image', [
'repository' => $input->repositoryName,
'branch' => $input->branch,
'ref' => $input->hexsha ?? $input->tag,
'client' => $client->getIp()
]);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
throw new BadRequestHttpException('Error deploying Git image');
}
$jobId = $response['job_id'];
$client->setStatus(ClientStatus::BUSY);
$this->entityManager->persist($client);
$this->entityManager->flush();
return $jobId;
}
}

View File

@ -21,7 +21,6 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpClient\Exception\TransportException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
@ -30,24 +29,29 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class DeployImageAction extends AbstractOgAgentController
class DeployImageAction extends AbstractController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
{
}
/**
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
*/
public function __invoke(ImageImageRepository $imageImageRepository, DeployImageInput $input, Client $client, ?string $method = null)
public function __invoke(ImageImageRepository $imageImageRepository, DeployImageInput $input, Client $client, string $method)
{
$image = $imageImageRepository->getImage();
if (!$client->getIp()) {
throw new BadRequestHttpException('IP is required');
}
if ($input->type === 'git') {
throw new BadRequestHttpException('Use DeployGitImageAction for Git images');
throw new ValidatorException('IP is required');
}
$method = match ($input->method) {
@ -56,7 +60,7 @@ class DeployImageAction extends AbstractOgAgentController
DeployMethodTypes::UNICAST_DIRECT => 'unicast-direct',
DeployMethodTypes::UNICAST => 'unicast',
DeployMethodTypes::TORRENT => 'torrent',
default => throw new BadRequestHttpException('Invalid method'),
default => throw new ValidatorException('Invalid method'),
};
$mcastMode = $input->mcastMode.'-duplex';
@ -70,7 +74,7 @@ class DeployImageAction extends AbstractOgAgentController
DeployMethodTypes::MULTICAST, DeployMethodTypes::MULTICAST_UFTP, DeployMethodTypes::MULTICAST_UFTP_DIRECT, DeployMethodTypes::MULTICAST_UDPCAST, DeployMethodTypes::MULTICAST_UDPCAST_DIRECT => $ptcMulticastValue,
DeployMethodTypes::UNICAST, DeployMethodTypes::UNICAST_DIRECT => $ptcUnicastValue,
DeployMethodTypes::TORRENT => $ptcTorrentValue,
default => throw new BadRequestHttpException('Invalid method'),
default => throw new ValidatorException('Invalid method'),
};
$repository = $imageImageRepository->getRepository();
@ -80,35 +84,33 @@ class DeployImageAction extends AbstractOgAgentController
'par' => (string) $input->partitionNumber,
'ifs' => "1",
'idi' => $image->getUuid(),
'nci' => $imageImageRepository->getName(),
'nci' => $image->getName(),
'ipr' => $repository->getIp(),
'nfn' => 'RestaurarImagen',
'ptc' => $ptcValue,
'ids' => '0'
];
$url = 'https://'.$client->getIp().':8000/opengnsys/RestaurarImagen';
$response = $this->createRequest(
method: 'POST',
url: $url,
params: [
try {
$response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/CloningEngine/RestaurarImagen', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
'json' => $data,
],
token: $client->getToken(),
);
]);
$this->logger->info('Deploying image', ['image' => $image->getId()]);
$this->logger->info('Deploying image', [
'image' => $imageImageRepository->getName(),
'repository' => $repository->getIp(),
'client' => $client->getIp()
]);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
throw new BadRequestHttpException('Error deploying image');
$jobId = json_decode($response->getContent(), true)['job_id'];
} catch (ClientExceptionInterface | ServerExceptionInterface | TransportExceptionInterface | TransportException $e) {
$this->logger->error('Error deploying image', [
'image' => $image->getId() ?? 'unknown',
'error' => $e->getMessage()
]);
return null;
}
$jobId = $response['job_id'];
$client->setStatus(ClientStatus::BUSY);
$this->entityManager->persist($client);

View File

@ -1,57 +0,0 @@
<?php
namespace App\Controller\OgAgent;
use App\Entity\Client;
use App\Model\CommandTypes;
use App\Model\TraceStatus;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class HardwareInventoryAction extends AbstractOgAgentController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(Client $client): JsonResponse
{
$data = [
'nfn' => 'InventarioHardware',
'ids' => '0'
];
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/InventarioHardware',
params: [
'json' => $data,
],
token: $client->getToken(),
);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
throw new BadRequestHttpException('Error performing hardware inventory: '.$response['error']);
}
$this->logger->info('Login client', ['client' => $client->getId()]);
$jobId = $response['job_id'];
$inputData = [
'client' => $client->getIp(),
];
$this->createService->__invoke($client, CommandTypes::HARDWARE_INVENTORY, TraceStatus::IN_PROGRESS, $jobId, $inputData);
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

View File

@ -1,71 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Controller\OgAgent;
use App\Dto\Input\KillJobInput;
use App\Entity\Trace;
use App\Model\ClientStatus;
use App\Model\CommandTypes;
use App\Model\TraceStatus;
use App\Service\Trace\CreateService;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class KillJobAction extends AbstractOgAgentController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(Trace $trace, KillJobInput $input): JsonResponse
{
$client = $trace->getClient();
if (!$client->getIp()) {
throw new BadRequestHttpException('IP is required');
}
$data = [
'job_id' => $input->jobId
];
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/KillJob',
params: [
'json' => $data,
],
token: $client->getToken(),
);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
throw new BadRequestHttpException('Error killing job: '.$response['error']);
}
$this->logger->info('Killing job', ['client' => $client->getId(), 'job_id' => $input->jobId]);
$trace->setStatus(TraceStatus::CANCELLED);
$this->entityManager->persist($trace);
$this->entityManager->flush();
$inputData = [
'job_id' => $input->jobId,
'client' => $client->getId(),
'trace' => $trace->getUuid(),
'command' => $trace->getCommand(),
];
$this->createService->__invoke($client, CommandTypes::KILL_JOB, TraceStatus::CANCELLED, $input->jobId, $inputData);
return new JsonResponse(data: $trace, status: Response::HTTP_OK);
}
}

View File

@ -1,94 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Controller\OgAgent;
use App\Dto\Input\BootClientsInput;
use App\Dto\Input\MultipleClientsInput;
use App\Entity\Client;
use App\Entity\Command;
use App\Entity\Image;
use App\Entity\Partition;
use App\Entity\Trace;
use App\Model\ClientStatus;
use App\Model\CommandTypes;
use App\Model\ImageStatus;
use App\Model\TraceStatus;
use App\Service\Trace\CreateService;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class LoginAction extends AbstractOgAgentController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(BootClientsInput $input): JsonResponse
{
/** @var Partition $partition */
$partition = $input->partition->getEntity();
foreach ($input->clients as $clientEntity) {
/** @var Client $client */
$client = $clientEntity->getEntity();
if (!$client->getIp()) {
throw new BadRequestHttpException('IP is required');
}
if ($client->getStatus() !== ClientStatus::OG_LIVE) {
$this->createService->__invoke($client, CommandTypes::LOGIN, TraceStatus::PENDING, null, []);
continue;
}
$data = [
'nfn' => 'IniciarSesion',
'dsk' => (string) $partition->getDiskNumber(),
'par' => (string) $partition->getPartitionNumber(),
'ids' => '0'
];
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/IniciarSesion',
params: [
'json' => $data,
],
token: $client->getToken(),
);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
$this->createService->__invoke($client, CommandTypes::LOGIN, TraceStatus::PENDING, null, []);
continue;
}
$this->logger->info('Login client', ['client' => $client->getId()]);
$jobId = $response['job_id'];
$client->setStatus(ClientStatus::INITIALIZING);
$this->entityManager->persist($client);
$this->entityManager->flush();
$this->createService->__invoke($client, CommandTypes::LOGIN, TraceStatus::SUCCESS, $jobId, []);
}
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

View File

@ -20,7 +20,6 @@ use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
@ -29,26 +28,26 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class PartitionAssistantAction extends AbstractOgAgentController
class PartitionAssistantAction extends AbstractController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
{
}
public function __invoke(PartitionPostInput $input): JsonResponse
{
$partitions = $input->partitions;
if (empty($partitions)) {
throw new BadRequestHttpException('Partitions is required');
throw new ValidatorException('Partitions is required');
}
$clientJobs = [];
foreach ($input->clients as $clientInput) {
/** @var Client $client */
$client = $clientInput->getEntity();
$disks = [];
@ -73,10 +72,13 @@ class PartitionAssistantAction extends AbstractOgAgentController
];
}
$disks[$diskNumber]['diskData'] = [
'dis' => (string) $diskNumber,
'tch' => (string) ($partition->size * 1024),
];
if ($partition->filesystem === 'CACHE') {
$disks[$diskNumber]['diskData'] = [
'dis' => (string) $diskNumber,
'che' => "0",
'tch' => (string) ($partition->size * 1024),
];
}
$disks[$diskNumber]['partitionData'][] = [
'par' => (string) $partition->partitionNumber,
@ -101,38 +103,32 @@ class PartitionAssistantAction extends AbstractOgAgentController
"ids" => "0"
];
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/Configurar',
params: [
try {
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/CloningEngine/Configurar', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
'json' => $result,
],
token: $client->getToken(),
);
$this->logger->info('Partition assistant', ['client' => $client->getId()]);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
if ($input->queue) {
$this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::PENDING, null, $data);
continue;
}
]);
$this->logger->info('Partitioning disk', ['client' => $client->getId(), 'disk' => $diskNumber]);
} catch (TransportExceptionInterface $e) {
$this->logger->error('Error partitioning disk', ['client' => $client->getId(), 'disk' => $diskNumber, 'error' => $e->getMessage()]);
continue;
}
$jobId = $response['job_id'];
$jobId = json_decode($response->getContent(), true)['job_id'];
$client->setStatus(ClientStatus::BUSY);
$this->entityManager->persist($client);
$this->entityManager->flush();
$this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::IN_PROGRESS, $jobId, $data);
$clientJobs['/clients/' . $client->getUuid()] = $jobId;
$this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::IN_PROGRESS, $jobId, []);
}
}
return new JsonResponse(data: $clientJobs, status: Response::HTTP_OK);
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

View File

@ -20,7 +20,6 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpClient\Exception\TransportException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
@ -29,14 +28,17 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class PowerOffAction extends AbstractOgAgentController
class PowerOffAction extends AbstractController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
{
}
public function __invoke(MultipleClientsInput $input): JsonResponse
{
foreach ($input->clients as $clientEntity) {
@ -44,10 +46,10 @@ class PowerOffAction extends AbstractOgAgentController
$client = $clientEntity->getEntity();
if (!$client->getIp()) {
throw new BadRequestHttpException('IP is required');
throw new ValidatorException('IP is required');
}
if ($client->getStatus() === ClientStatus::OFF || $client->getStatus() === ClientStatus::TURNING_OFF || $client->getStatus() === ClientStatus::DISCONNECTED) {
if ($client->getStatus() === ClientStatus::OFF) {
continue;
}
@ -56,30 +58,26 @@ class PowerOffAction extends AbstractOgAgentController
'ids' => '0'
];
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/Apagar',
params: [
try {
$response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/ogAdmClient/Apagar', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
'json' => $data,
],
token: $client->getToken(),
);
]);
$this->logger->info('Powering off client', ['client' => $client->getId()]);
$jobId = json_decode($response->getContent(), true)['job_id'];
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
$this->logger->error('Error powering off client', ['client' => $client->getId(), 'error' => $response['error']]);
if ($input->queue) {
$this->createService->__invoke($client, CommandTypes::SHUTDOWN, TraceStatus::PENDING, null, []);
continue;
}
} catch (ClientExceptionInterface | ServerExceptionInterface | TransportExceptionInterface | TransportException $e) {
$this->logger->error('Error power off client', [
'image' => $client->getIp(),
'error' => $e->getMessage()
]);
continue;
}
$this->logger->info('Powering off client', ['client' => $client->getId()]);
$jobId = $response['job_id'];
$client->setStatus(ClientStatus::TURNING_OFF);
$this->entityManager->persist($client);
$this->entityManager->flush();

View File

@ -19,7 +19,6 @@ use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
@ -28,23 +27,25 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class RebootAction extends AbstractOgAgentController
class RebootAction extends AbstractController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
{
}
public function __invoke(MultipleClientsInput $input): JsonResponse
{
foreach ($input->clients as $clientEntity) {
/** @var Client $client */
$client = $clientEntity->getEntity();
if (!$client->getIp()) {
throw new BadRequestHttpException('IP is required');
throw new ValidatorException('IP is required');
}
$data = [
@ -52,27 +53,26 @@ class RebootAction extends AbstractOgAgentController
'ids' => '0'
];
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/Reiniciar',
params: [
try {
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/ogAdmClient/Reiniciar', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
'json' => $data,
],
token: $client->getToken(),
);
]);
$this->logger->info('Rebooting client', ['client' => $client->getId()]);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
if ($input->queue) {
$this->createService->__invoke($client, CommandTypes::REBOOT, TraceStatus::PENDING, null, []);
continue;
}
continue;
} catch (TransportExceptionInterface $e) {
$this->logger->error('Error rebooting client', ['client' => $client->getId(), 'error' => $e->getMessage()]);
return new JsonResponse(
data: ['error' => $e->getMessage()],
status: Response::HTTP_INTERNAL_SERVER_ERROR
);
}
$this->logger->info('Rebooting client', ['client' => $client->getId()]);
$jobId = $response['job_id'];
$jobId = json_decode($response->getContent(), true)['job_id'];
$client->setStatus(ClientStatus::INITIALIZING);
$this->entityManager->persist($client);

View File

@ -1,91 +0,0 @@
<?php
namespace App\Controller\OgAgent;
use App\Dto\Input\BootClientsInput;
use App\Entity\Client;
use App\Entity\Partition;
use App\Model\ClientStatus;
use App\Model\CommandTypes;
use App\Model\TraceStatus;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class RemoveCacheImageAction extends AbstractOgAgentController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(BootClientsInput $input): JsonResponse
{
/** @var Partition $partition */
$partition = $input->partition->getEntity();
foreach ($input->clients as $clientEntity) {
/** @var Client $client */
$client = $clientEntity->getEntity();
if (!$partition->getImage()) {
throw new BadRequestHttpException('Image is required');
}
if (!$client->getIp()) {
throw new BadRequestHttpException('IP is required');
}
if ($client->getStatus() !== ClientStatus::OG_LIVE) {
$this->createService->__invoke($client, CommandTypes::REMOVE_CACHE_IMAGE, TraceStatus::PENDING, null, []);
continue;
}
$script = 'rm -r /opt/opengnsys/cache/opt/opengnsys/images/' . $partition->getImage()->getName() . '.*';
$data = [
'nfn' => 'EjecutarScript',
'scp' => base64_encode($script),
'ids' => '0'
];
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/EjecutarScript',
params: [
'json' => $data,
],
token: $client->getToken(),
);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
if ($input->queue) {
$this->createService->__invoke($client, CommandTypes::REMOVE_CACHE_IMAGE, TraceStatus::PENDING, null, []);
continue;
}
continue;
}
$this->logger->info('Login client', ['client' => $client->getId()]);
$jobId = $response['job_id'];
$this->entityManager->persist($client);
$this->entityManager->flush();
$inputData = [
'script' => $script,
];
$this->createService->__invoke($client, CommandTypes::RUN_SCRIPT, TraceStatus::SUCCESS, $jobId, $inputData);
}
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

View File

@ -1,93 +0,0 @@
<?php
namespace App\Controller\OgAgent;
use App\Dto\Input\CommandExecuteInput;
use App\Dto\Input\MultipleClientsInput;
use App\Entity\Client;
use App\Model\ClientStatus;
use App\Model\CommandTypes;
use App\Model\TraceStatus;
use App\Service\Trace\CreateService;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class RunScriptAction extends AbstractOgAgentController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(CommandExecuteInput $input): JsonResponse
{
$clientJobs = [];
/** @var Client $clientEntity */
foreach ($input->clients as $clientEntity) {
/** @var Client $client */
$client = $clientEntity->getEntity();
if (!$client->getIp()) {
throw new BadRequestHttpException('IP is required');
}
$data = [
'nfn' => 'EjecutarScript',
'scp' => base64_encode($input->script),
'ids' => '0'
];
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/EjecutarScript',
params: [
'json' => $data,
],
token: $client->getToken(),
);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
$this->logger->error('Error running script', ['client' => $client->getId(), 'error' => $response['error']]);
if ($input->queue) {
$inputData = [
'script' => $input->script,
];
$this->createService->__invoke($client, CommandTypes::RUN_SCRIPT, TraceStatus::PENDING, null, $inputData);
continue;
}
continue;
}
$this->logger->info('Powering off client', ['client' => $client->getId()]);
$jobId = $response['job_id'];
$clientJobs[(string) '/clients/' . $client->getUuid()] = $jobId;
$this->entityManager->persist($client);
$this->entityManager->flush();
$inputData = [
'script' => $input->script,
];
$this->createService->__invoke($client, CommandTypes::RUN_SCRIPT, TraceStatus::IN_PROGRESS, $jobId, $inputData);
}
return new JsonResponse(data: $clientJobs, status: Response::HTTP_OK);
}
}

View File

@ -1,62 +0,0 @@
<?php
namespace App\Controller\OgAgent;
use App\Dto\Input\SoftwareInventoryPartitionInput;
use App\Entity\Client;
use App\Model\CommandTypes;
use App\Model\TraceStatus;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class SoftwareInventoryAction extends AbstractOgAgentController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(Client $client, SoftwareInventoryPartitionInput $input): JsonResponse
{
$data = [
'nfn' => 'InventarioSoftware',
'ids' => '0',
'dsk' => (string) $input->partition->getEntity()->getDiskNumber(),
'par' => (string) $input->partition->getEntity()->getPartitionNumber(),
];
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/InventarioSoftware',
params: [
'json' => $data,
],
token: $client->getToken(),
);
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
throw new BadRequestHttpException('Error performing software inventory: '.$response['error']);
}
$this->logger->info('Login client', ['client' => $client->getId()]);
$jobId = $response['job_id'];
$inputData = [
'partition' => $input->partition->getEntity()->getUuid(),
'image' => $input->partition->getEntity()->getImage()?->getUuid(),
'client' => $client->getIp(),
];
$this->createService->__invoke($client, CommandTypes::SOFTWARE_INVENTORY, TraceStatus::IN_PROGRESS, $jobId, $inputData);
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

Some files were not shown because too many files have changed in this diff Show More