Compare commits

...

157 Commits

Author SHA1 Message Date
Manuel Aranda Rosales 785fd5b8ab refs #2591. new response. Added job_id
testing/ogcore-api/pipeline/head There was a failure building this commit Details
ogcore-debian-package/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-08-04 12:42:32 +02:00
Manuel Aranda Rosales 4d9b6c856e refs #2591. new response. Added job_id
testing/ogcore-api/pipeline/head There was a failure building this commit Details
ogcore-debian-package/pipeline/head This commit looks good Details
2025-08-04 12:38:30 +02:00
Manuel Aranda Rosales 4a4771f8eb refs #2591. new response. Added job_id
testing/ogcore-api/pipeline/head There was a failure building this commit Details
ogcore-debian-package/pipeline/head This commit looks good Details
2025-08-04 12:37:23 +02:00
Manuel Aranda Rosales 3c78984217 refs #2591. new response. Added job_id
testing/ogcore-api/pipeline/head There was a failure building this commit Details
ogcore-debian-package/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-08-04 11:00:29 +02:00
Manuel Aranda Rosales 49d09e1952 refs #2591. new response. Added job_id
ogcore-debian-package/pipeline/head There was a failure building this commit Details
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-08-04 10:51:22 +02:00
Manuel Aranda Rosales bc80b3af7c refs #2591. new response. Added job_id 2025-08-04 10:50:11 +02:00
Manuel Aranda Rosales 82d5edb55b refs #2540. Fixed bug when delete client
ogcore-debian-package/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/head This commit looks good Details
2025-07-29 12:22:34 +02:00
Nicolas Arenas 177b95f1b6 cronjobs (#42)
ogcore-debian-package/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/head This commit looks good Details
Reviewed-on: #42
2025-07-28 12:46:26 +02:00
Manuel Aranda Rosales ec427b176b Merge pull request 'develop' (#41) from develop into main
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
Reviewed-on: #41
2025-06-27 13:57:53 +02:00
Manuel Aranda Rosales c42c50e29b Merge branch 'main' into develop
testing/ogcore-api/pipeline/pr-main Build queued... Details
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-06-27 13:56:55 +02:00
Manuel Aranda Rosales b7ecef6e4b Added changelog
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-06-27 13:56:30 +02:00
Manuel Aranda Rosales 9d38db44e0 Merge pull request 'Updated template to new html' (#40) from develop into main
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
Reviewed-on: #40
2025-06-27 12:42:29 +02:00
Manuel Aranda Rosales f59fdd87ec Updated template to new html
testing/ogcore-api/pipeline/pr-main Build queued... Details
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-06-27 12:42:06 +02:00
Manuel Aranda Rosales d4856d12aa Merge pull request 'develop' (#39) from develop into main
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
Reviewed-on: #39
2025-06-27 12:21:30 +02:00
Manuel Aranda Rosales b15154019c Merge branch 'main' into develop
testing/ogcore-api/pipeline/pr-main Build queued... Details
2025-06-27 12:21:13 +02:00
Manuel Aranda Rosales ad90a42c2c Updated template to new html
testing/ogcore-api/pipeline/pr-main Build started... Details
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-06-27 12:19:07 +02:00
Nicolas Arenas beb261a914 Update nginx file to serve real time logs from clientes
testing/ogcore-api/pipeline/head This commit looks good Details
2025-06-27 09:48:48 +02:00
Manuel Aranda Rosales 0ce5541bac Merge pull request 'Fixed p2ptime default' (#38) from develop into main
testing/ogcore-api/pipeline/head There was a failure building this commit Details
ogcore-debian-package/pipeline/head This commit looks good Details
Reviewed-on: #38
2025-06-27 09:18:44 +02:00
Manuel Aranda Rosales ce8ac4c2d0 Merge branch 'main' into develop
testing/ogcore-api/pipeline/pr-main Build queued... Details
2025-06-27 09:18:17 +02:00
Manuel Aranda Rosales 2f635fdfdf Fixed p2ptime default
testing/ogcore-api/pipeline/head Build started... Details
testing/ogcore-api/pipeline/pr-main Build started... Details
2025-06-27 09:17:24 +02:00
Manuel Aranda Rosales 69bbf3e209 Merge pull request 'develop' (#37) from develop into main
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
Reviewed-on: #37
2025-06-26 17:21:00 +02:00
Manuel Aranda Rosales 966936c4f2 Merge branch 'main' into develop
testing/ogcore-api/pipeline/pr-main Build started... Details
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-06-26 17:20:34 +02:00
Manuel Aranda Rosales 2588dd07f2 Added changelog
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-06-26 17:19:17 +02:00
Manuel Aranda Rosales 21cd73bee2 refs #2252. Queue actions. Empty queue and logging actions
testing/ogcore-api/pipeline/head This commit looks good Details
2025-06-26 17:10:44 +02:00
Manuel Aranda Rosales 7b74c9ab70 refs #2327. KillJob integration
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-06-26 17:08:40 +02:00
Manuel Aranda Rosales e325578e2b refs #1975. Integration ogGit. Crete image and deploy
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-06-26 17:06:48 +02:00
Manuel Aranda Rosales e51e1e13ea refs #1975. Integration ogGit. Crete image and deploy
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-06-26 17:04:50 +02:00
Manuel Aranda Rosales af5ad81199 refs #1975. Integration ogGit. Crete image and deploy
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-06-26 17:01:16 +02:00
Manuel Aranda Rosales 5e143e08a9 Merge pull request 'develop' (#36) from develop into main
ogcore-debian-package/pipeline/head This commit looks good Details
Reviewed-on: #36
2025-06-09 14:07:48 +02:00
Manuel Aranda Rosales 73f65e65a2 Change menu template. python scripts 2025-06-09 14:06:52 +02:00
Manuel Aranda Rosales abde95c641 Merge branch 'main' into develop 2025-06-09 11:54:14 +02:00
Manuel Aranda Rosales fbdf569cf3 Merge pull request 'develop' (#35) from develop into main
ogcore-debian-package/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
Reviewed-on: #35
2025-06-09 11:53:37 +02:00
Manuel Aranda Rosales 2609053406 Merge branch 'main' into develop 2025-06-09 11:53:10 +02:00
Manuel Aranda Rosales 119c24f4e5 refs #2181. Changed Output messages 2025-06-09 11:51:43 +02:00
Manuel Aranda Rosales ca4cdafc01 refs #2181. Changed Output messages 2025-06-09 11:43:14 +02:00
Manuel Aranda Rosales 925a486379 Updated env.json data
ogcore-debian-package/pipeline/head This commit looks good Details
2025-06-05 09:47:28 +02:00
Manuel Aranda Rosales 150b437656 Merge pull request 'develop' (#34) from develop into main
ogcore-debian-package/pipeline/head There was a failure building this commit Details
ogcore-debian-package/pipeline/tag There was a failure building this commit Details
Reviewed-on: #34
2025-06-02 07:47:07 +02:00
Manuel Aranda Rosales 0b2faa1222 Added changelog 2025-06-02 07:44:25 +02:00
Manuel Aranda Rosales b7da3bd639 refs #2120. Fixed test 2025-06-02 07:39:00 +02:00
Manuel Aranda Rosales d13e24cc23 refs #2120. Remove pxe template when removed client 2025-06-02 07:35:27 +02:00
Manuel Aranda Rosales 64eeb5c88e refs #2133. CHanged PXE template 2025-06-02 00:17:42 +02:00
Manuel Aranda Rosales 7d59467acc refs #2120. Remove pxe template when removed client 2025-06-02 00:15:03 +02:00
Manuel Aranda Rosales f9a00fd319 refs #2120. Remove pxe template when removed client 2025-06-02 00:13:20 +02:00
Manuel Aranda Rosales 1bd32a32bb refs #2098. Move clients to different OU 2025-06-02 00:10:47 +02:00
Manuel Aranda Rosales d99493ac46 refs #2085. RemoveCacheImage 2025-06-02 00:08:57 +02:00
Manuel Aranda Rosales b2684a71ad refs #2132. 1 minute disconnected 2025-05-30 12:28:21 +02:00
Manuel Aranda Rosales de33d665de refs #2120. Remove pxe template when removed client 2025-05-30 12:14:36 +02:00
Manuel Aranda Rosales b86e51e1bb refs #2137. Removed subred fixed
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-30 08:37:36 +02:00
Manuel Aranda Rosales 6abf065dec Published validate endpoint
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-27 13:37:12 +02:00
Manuel Aranda Rosales d33c6ea48e Changed SSl_ENABLED default false
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-23 09:32:00 +02:00
Manuel Aranda Rosales 1e45534942 Changed SSl_ENABLED default false
testing/ogcore-api/pipeline/head There was a failure building this commit Details
ogcore-debian-package/pipeline/tag There was a failure building this commit Details
ogcore-debian-package/pipeline/head There was a failure building this commit Details
2025-05-23 09:30:44 +02:00
Manuel Aranda Rosales ee76f7aa11 refs #2085. RemoveCacheImage
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-23 09:24:05 +02:00
Manuel Aranda Rosales 9be2f5fd9b refs #2085. Boot OS
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-23 09:23:41 +02:00
Manuel Aranda Rosales 76a90d1129 refs #2084. New env to ogBoot
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-22 18:29:19 +02:00
Manuel Aranda Rosales a3f271a9ae Added trace date filter
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-20 16:25:54 +02:00
Manuel Aranda Rosales 7e410e234c Merge pull request 'develop' (#33) from develop into main
ogcore-debian-package/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
Reviewed-on: #33
2025-05-19 16:50:46 +02:00
Manuel Aranda Rosales 5cf001f3e2 Merge branch 'main' into develop
testing/ogcore-api/pipeline/pr-main Build started... Details
2025-05-19 16:50:27 +02:00
Manuel Aranda Rosales 1a232e93c7 Added changelog
testing/ogcore-api/pipeline/head There was a failure building this commit Details
testing/ogcore-api/pipeline/pr-main There was a failure building this commit Details
2025-05-19 16:48:13 +02:00
Manuel Aranda Rosales 294a9c5d40 Improvements
testing/ogcore-api/pipeline/head This commit looks good Details
2025-05-19 16:42:22 +02:00
Manuel Aranda Rosales 6c1b28176a Improvements
testing/ogcore-api/pipeline/head This commit looks good Details
2025-05-19 16:13:08 +02:00
Manuel Aranda Rosales 6425e4aaa6 Fixed docker default.conf nginx file
testing/ogcore-api/pipeline/head This commit looks good Details
2025-05-19 11:11:14 +02:00
Manuel Aranda Rosales 684d25c8d3 Docker certs volume
testing/ogcore-api/pipeline/head This commit looks good Details
2025-05-19 08:15:10 +02:00
Manuel Aranda Rosales 0396085249 refs #2031. Added secret in Client. Refactor ogAgent TLS
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-19 08:05:08 +02:00
Manuel Aranda Rosales c8ca90a37b Merge pull request 'develop' (#32) from develop into main
ogcore-debian-package/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/head This commit looks good Details
Reviewed-on: #32
2025-05-14 23:03:21 +02:00
Manuel Aranda Rosales dce63d1331 solve conflicts
testing/ogcore-api/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/pr-main Build started... Details
2025-05-14 13:30:29 +02:00
Manuel Aranda Rosales 527383bce1 solve conflicts
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-05-14 13:28:02 +02:00
Manuel Aranda Rosales 326ff47edd Some improvements
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-14 13:25:57 +02:00
Nicolas Arenas d04e727f02 Adjusted values in env.json
ogcore-debian-package/pipeline/head This commit looks good Details
2025-05-14 06:35:39 +02:00
Manuel Aranda Rosales db216660bb Merge pull request 'develop' (#31) from develop into main
ogcore-debian-package/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
Reviewed-on: #31
2025-05-13 09:22:09 +02:00
Manuel Aranda Rosales 36c2abc98f Solve conflics 2025-05-13 09:21:05 +02:00
Manuel Aranda Rosales 9528372599 Added changelog 2025-05-13 09:16:24 +02:00
Manuel Aranda Rosales 9673c9c09a refs #1975. Integration ogGit. Create table and init API 2025-05-13 09:10:10 +02:00
Manuel Aranda Rosales 1f6f4164d0 refs #1984. Git integration UX changes 2025-05-12 16:35:40 +02:00
Manuel Aranda Rosales 816b31a7ed refs #1975. Integration ogGit. Create table and init API
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-08 17:03:04 +02:00
Manuel Aranda Rosales 43f81a833e refs #1975. Integration ogGit. Create table and init API
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-08 17:02:27 +02:00
Manuel Aranda Rosales 6df1057b20 refs #1973. Linked image to partition
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-08 16:36:04 +02:00
Manuel Aranda Rosales 7f5ed49f97 refs #1967. Sync ogBoot API when put template 2025-05-07 17:26:08 +02:00
Manuel Aranda Rosales 7ac0a62e9e refs #1967. Sync ogBoot API when put template
testing/ogcore-api/pipeline/head This commit looks good Details
2025-05-07 17:12:19 +02:00
Manuel Aranda Rosales ef9aee0368 refs #1967. Sync ogBoot API when put template
testing/ogcore-api/pipeline/head This commit looks good Details
2025-05-07 17:07:48 +02:00
Manuel Aranda Rosales 927e38102e refs #1967. Sync ogBoot API when put template 2025-05-07 17:02:57 +02:00
Manuel Aranda Rosales d347896158 refs #1966. RunScheduleCommand
testing/ogcore-api/pipeline/head This commit looks good Details
2025-05-07 16:59:20 +02:00
Manuel Aranda Rosales 53a8c04e76 refs #1951. Added isDefault in PxeTemplate entity
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-07 16:57:55 +02:00
Manuel Aranda Rosales 410b287d05 refs #1826. Change some env var
testing/ogcore-api/pipeline/head This commit looks good Details
2025-05-07 16:54:24 +02:00
Manuel Aranda Rosales 24c5451f52 refs #1826. Change some env var
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-07 16:54:01 +02:00
Manuel Aranda Rosales 0d36ca39dd refs #1965. New remoteCalendar rule
testing/ogcore-api/pipeline/head This commit looks good Details
2025-05-07 16:33:36 +02:00
Manuel Aranda Rosales d4d2bad691 Modified null default params
testing/ogcore-api/pipeline/head This commit looks good Details
2025-05-07 12:49:27 +02:00
Manuel Aranda Rosales b942ac9a8e Modified logger transfer action
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-05-07 12:47:26 +02:00
Manuel Aranda Rosales 51cc5fac2c refs #1943. Updated createTrace service
testing/ogcore-api/pipeline/head This commit looks good Details
2025-04-30 12:35:02 +02:00
Manuel Aranda Rosales e48917181f refs #1943. Added PXE template to NetworkSettings 2025-04-30 12:34:20 +02:00
Manuel Aranda Rosales 68a2e4f205 refs #1942. Updated COmmandTask logic. Created new tables and API commandTaskScript and commandTaskSchedule 2025-04-30 12:32:53 +02:00
Manuel Aranda Rosales 531c56630f refs #1942. Updated COmmandTask logic. Created new tables and API commandTaskScript and commandTaskSchedule
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-30 12:30:59 +02:00
Nicolas Arenas e455e6228c updated control
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
ogcllient/pipeline/head This commit looks good Details
2025-04-29 15:41:19 +02:00
Manuel Aranda Rosales ed13a7adec Deleted test command
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
2025-04-23 17:42:36 +02:00
Manuel Aranda Rosales 4a9749c97c Updated changelog
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag There was a failure building this commit Details
2025-04-23 17:29:05 +02:00
Manuel Aranda Rosales fbb694581e Updated ogAgent ping updatedAt. Fixed server date
testing/ogcore-api/pipeline/head This commit looks good Details
2025-04-23 17:19:35 +02:00
Nicolas Arenas 8d61a564a4 Add cronjob to check client status
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
2025-04-22 11:08:37 +02:00
Manuel Aranda Rosales 6a24fa1017 Merge pull request 'develop' (#29) from develop into main
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
Reviewed-on: #29
2025-04-16 11:58:32 +02:00
Manuel Aranda Rosales 39a78feabe Merge branch 'main' into develop
testing/ogcore-api/pipeline/pr-main Build queued... Details
testing/ogcore-api/pipeline/head There was a failure building this commit Details
ogcore-debian-package/pipeline/head This commit looks good Details
2025-04-16 11:58:03 +02:00
Manuel Aranda Rosales c259dc6b32 Added changelog
testing/ogcore-api/pipeline/pr-main Build started... Details
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-16 11:56:35 +02:00
Manuel Aranda Rosales 154472ac30 refs #1923. Fixed bug create imagen processor
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-16 11:54:09 +02:00
Manuel Aranda Rosales 351f952cba Merge pull request 'develop' (#27) from develop into main
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
Reviewed-on: #27
2025-04-11 12:00:09 +02:00
Manuel Aranda Rosales aaa8854839 Merge branch 'main' into develop
testing/ogcore-api/pipeline/pr-main This commit looks good Details
2025-04-11 11:55:14 +02:00
Manuel Aranda Rosales b1fbc4787a Changed CHANGELOG
testing/ogcore-api/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/pr-main There was a failure building this commit Details
2025-04-11 09:08:20 +02:00
Manuel Aranda Rosales 0cce7ff52d Some improvements. Sync multi clients ogBoot. Added base64 encode run script
testing/ogcore-api/pipeline/head This commit looks good Details
2025-04-11 08:14:07 +02:00
Nicolas Arenas eec19314ee Allos to publish in main
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
2025-04-10 16:31:22 +02:00
Nicolas Arenas be23dd538b Allos to publish in main
ogcore-debian-package/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-10 16:29:56 +02:00
Manuel Aranda Rosales 290cbb0ae0 Image improvements. Added name
testing/ogcore-api/pipeline/head This commit looks good Details
2025-04-10 09:54:50 +02:00
Manuel Aranda Rosales 9a96b04e7f refs #1864. Added ssh_port and user in imageRepository
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-10 09:53:28 +02:00
Manuel Aranda Rosales 4578f29349 refs #1857. Rename image API integration
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-10 09:50:59 +02:00
Manuel Aranda Rosales 6867f74098 refs #1858. Added description into deployImage selector
testing/ogcore-api/pipeline/head This commit looks good Details
2025-04-09 17:58:29 +02:00
Manuel Aranda Rosales 1bca31ec5f refs #1855. Fixed subnet DTOs clients property
testing/ogcore-api/pipeline/head This commit looks good Details
2025-04-08 15:43:14 +02:00
Manuel Aranda Rosales 927677ddc0 refs #1858. Added description into imageImageRepositort
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-08 15:42:53 +02:00
Manuel Aranda Rosales 097c6a710e refs #1851. Added script/funcionality to check PC availability
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-08 15:34:25 +02:00
Manuel Aranda Rosales b6c62996f5 refs #1855. Fixed subnet DTOs clients property
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-07 15:22:45 +02:00
Manuel Aranda Rosales beeda955ef OgRepo createImage improvements. Agent Status fixed
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-07 08:23:12 +02:00
Manuel Aranda Rosales d8306f78a7 refs #1797. Rename image. Versions added
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-03 08:41:59 +02:00
Manuel Aranda Rosales e119c14451 refs #1741. Syslog
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-02 21:28:39 +02:00
Manuel Aranda Rosales 912cf9b008 refs #1797. Rename image. Crete image
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-04-01 19:44:59 +02:00
Manuel Aranda Rosales bc036b65cf refs #1740. Run assistant logic
testing/ogcore-api/pipeline/head This commit looks good Details
2025-04-01 10:58:55 +02:00
Manuel Aranda Rosales 2d6b058eaf refs #1794. Updted assistants endpoints 2025-04-01 10:58:11 +02:00
Nicolas Arenas 421f5ff78e Adjust rules
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-03-27 09:21:27 +01:00
Nicolas Arenas e3d8a520ca Adjust rules
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag There was a failure building this commit Details
2025-03-27 09:15:35 +01:00
Nicolas Arenas 8b9328b6a3 Adjust rules
ogcore-debian-package/pipeline/tag There was a failure building this commit Details
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-27 09:12:19 +01:00
Nicolas Arenas 46bd3a68dc Update Jenkinsfile
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag There was a failure building this commit Details
2025-03-27 09:04:22 +01:00
Manuel Aranda Rosales 3eca490d0a Updated load default user command
testing/ogcore-api/pipeline/head There was a failure building this commit Details
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-03-26 21:54:39 +01:00
Manuel Aranda Rosales 52a0493285 Updated load default user command 2025-03-26 21:54:39 +01:00
Nicolas Arenas 24a414ab66 Add ogcore
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-03-26 18:17:40 +01:00
Nicolas Arenas 6b228b146b Updated ogcore
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-26 13:48:45 +01:00
Nicolas Arenas e646b4b1e9 Creates repo at install
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-03-26 13:46:16 +01:00
Manuel Aranda Rosales fbe20ba735 Fixed prod env web_profiler
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-03-26 08:42:07 +01:00
Manuel Aranda Rosales 9c8697740e Merge pull request 'develop' (#26) from develop into main
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag There was a failure building this commit Details
Reviewed-on: #26
2025-03-26 06:42:34 +01:00
Manuel Aranda Rosales 84d757415c Added changelog
testing/ogcore-api/pipeline/pr-main Build started... Details
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-03-26 06:41:20 +01:00
Manuel Aranda Rosales bbb9239f02 Merge branch 'develop' 2025-03-25 15:59:07 +01:00
Nicolas Arenas 27615adc98 Updated mercure endpoint for ogcore
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-03-20 10:39:28 +01:00
Nicolas Arenas aa62d31b62 Fixing some stuff for packaging
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-03-20 07:40:49 +01:00
Manuel Aranda Rosales a06a0998f9 Updated ogrepo sync funcionality
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-19 16:49:31 +01:00
Manuel Aranda Rosales 2f813099c5 Updated ogrepo sync funcionality
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-19 16:04:55 +01:00
Manuel Aranda Rosales a2e0ced906 refs #1731. New endpoint integration. Convert image to virtual
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-19 15:45:07 +01:00
Manuel Aranda Rosales 5be87008c4 refs #1701. Updated Sync with ogLive. Parse new data 2025-03-19 15:44:35 +01:00
Nicolas Arenas 7cc0a44650 Fix typo in Jenkinsfile
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/tag This commit looks good Details
2025-03-19 12:15:29 +01:00
Nicolas Arenas 18f3512e5b jenkins_upload_packages (#25)
testing/ogcore-api/pipeline/head This commit looks good Details
ogcore-debian-package/pipeline/head This commit looks good Details
Updates Jenkinsfile to upload packages to repo if they come from release

Reviewed-on: #25
refers #1313
2025-03-19 12:11:36 +01:00
Manuel Aranda Rosales 1f4a88df0f Refactor Images/Repositories modules
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-18 17:11:13 +01:00
Manuel Aranda Rosales ec7006db9a Refactor transferImages
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-18 08:42:25 +01:00
Manuel Aranda Rosales c2fed1fb15 Refactor transferImages
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-17 16:51:33 +01:00
Manuel Aranda Rosales b41c489ce3 Refactor transferImages
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-17 16:48:29 +01:00
Manuel Aranda Rosales 4a76186e97 Test refactor transferImage
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-17 08:55:42 +01:00
Manuel Aranda Rosales 88ffad3841 Merge branch 'main' into develop
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-13 14:38:33 +01:00
Manuel Aranda Rosales 8bc9cb1006 refs #1702. Updated ogLive sync. Deleted wrong or uninstalled oglives
testing/ogcore-api/pipeline/head There was a failure building this commit Details
2025-03-13 12:55:49 +01:00
Manuel Aranda Rosales 663b0d1928 refs #1671. Udpated deploy method type. Added udpcast-direct'
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-13 11:11:15 +01:00
Manuel Aranda Rosales 4051497761 refs #1693. Convert Image. Webhook updated.
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-12 17:35:24 +01:00
Manuel Aranda Rosales 868a015902 Merge branch 'main' into develop 2025-03-12 09:23:29 +01:00
Manuel Aranda Rosales fca9bb3ae3 refs #1693. Convert Image. Experimental commit
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-12 08:30:15 +01:00
Manuel Aranda Rosales b9e894f2d0 refs #1692. Import Image. Changes in logic
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-12 08:25:45 +01:00
Manuel Aranda Rosales 7c37bd418a refs #1692. Import Image. Changes
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-11 17:37:44 +01:00
Manuel Aranda Rosales 350dcd1d24 refs #1692. Import Image.
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-11 17:21:11 +01:00
Manuel Aranda Rosales dc9e21b61e refs #1693. Convert Image. Refactor old code
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-11 17:09:36 +01:00
Manuel Aranda Rosales b180d32843 refs #1692. Import Image. Refactor old code
testing/ogcore-api/pipeline/head This commit looks good Details
2025-03-11 15:49:07 +01:00
275 changed files with 8914 additions and 1420 deletions

View File

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

3
.gitignore vendored
View File

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

View File

@ -1,22 +1,168 @@
# 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.
@ -26,24 +172,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.
@ -51,7 +197,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.
@ -66,4 +212,5 @@
- **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,16 +48,51 @@ 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 {
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 && mkdir -p /var/tmp/opengnsys/debian-repo"
scp -r ../artifacts/* aptly@172.17.8.68:/var/tmp/opengnsys/debian-repo/
'''
script {
construirPaquete(env.BUILD_DIR, "../artifacts", "172.17.8.68", "/var/tmp/opengnsys/debian-repo/ogcore")
}
}
}
stage ('Publish to Debian Repository') {
when {
expression {
return env.TAG_NAME != null
}
}
agent { label 'debian-repo' }
steps {
script {
// Construir el patrón de versión esperado en el nombre del paquete
def versionPattern = "${env.TAG_NAME}-${env.BUILD_NUMBER}"
publicarEnAptly('/var/tmp/opengnsys/debian-repo/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)
}
}
}
@ -68,10 +103,5 @@ pipeline {
}
}
}
// stage ('Publish to Debian Repository') {
// agent { label 'debian-repo' }
// steps {
// 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-units
uriTemplate: /clients/change-organizational-unit
controller: App\Controller\ChangeOrganizationalUnitAction
agent_status:
@ -50,6 +50,34 @@ 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,6 +7,8 @@ resources:
groups: ['default', 'command:read']
denormalizationContext:
groups: ['command:write']
order:
id: 'DESC'
operations:
ApiPlatform\Metadata\GetCollection:
provider: App\State\Provider\CommandProvider
@ -28,9 +30,8 @@ resources:
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\CommandExecuteInput
uriTemplate: /commands/{uuid}/execute
controller: App\Controller\CommandExecuteAction
uriTemplate: /commands/run-script
controller: App\Controller\OgAgent\RunScriptAction
properties:
App\Entity\Command:
id:

View File

@ -0,0 +1,32 @@
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

@ -0,0 +1,32 @@
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

@ -0,0 +1,109 @@
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,6 +56,22 @@ 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
@ -88,7 +104,7 @@ resources:
description: Export Image in OgRepository
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\ExportImportImageRepositoryInput
input: App\Dto\Input\TransferGlobalImageInput
uriTemplate: /image-image-repositories/{uuid}/transfer-image
controller: App\Controller\OgRepository\Image\TransferAction
@ -101,6 +117,15 @@ 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\SyncAction
controller: App\Controller\OgRepository\Image\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\GetCollectionAction
controller: App\Controller\OgRepository\Image\GetCollectionAction
images_ogrepository_status:
shortName: OgRepository Server
@ -57,14 +57,50 @@ resources:
uriTemplate: /image-repositories/server/{uuid}/status
controller: App\Controller\OgRepository\StatusAction
export_image_ogrepository:
import_image_ogrepository:
shortName: OgRepository Server
description: Export Image in OgRepository
class: ApiPlatform\Metadata\Post
method: POST
input: App\Dto\Input\ExportImportImageRepositoryInput
uriTemplate: /image-repositories/{uuid}/export-image
controller: App\Controller\OgRepository\Image\ExportAction
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
properties:
App\Entity\ImageRepository:

View File

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

View File

@ -13,6 +13,7 @@ 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,6 +9,8 @@ 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
@ -21,6 +23,24 @@ 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,6 +12,7 @@ framework:
handler_id: null
cookie_secure: auto
cookie_samesite: lax
storage_factory_id: session.storage.factory.native
#esi: true
#fragments: true

View File

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

View File

@ -33,6 +33,7 @@ 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,3 +156,13 @@ 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,6 +41,52 @@ 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' ]
@ -61,7 +107,7 @@ services:
api_platform.filter.image.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial', 'repository.id': 'exact', status: 'exact'} ]
arguments: [ { 'id': 'exact', 'name': 'partial', 'repository.id': 'exact', status: 'exact', type: 'exact' } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.image.boolean:
@ -73,6 +119,10 @@ 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:
@ -82,7 +132,7 @@ services:
api_platform.filter.og_live.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial', } ]
arguments: [ { 'id': 'exact', 'name': 'partial', 'status': 'exact' } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.og_live.boolean:
@ -167,7 +217,7 @@ services:
api_platform.filter.pxe_template.boolean:
parent: 'api_platform.doctrine.orm.boolean_filter'
arguments: [ { 'synchronized': ~ } ]
arguments: [ { 'synchronized': ~, 'isDefault': ~ } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.remote_calendar.order:
@ -231,7 +281,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:
@ -248,7 +298,7 @@ services:
api_platform.filter.trace.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'command.id': 'exact', 'client.id': 'exact', status: 'exact' } ]
arguments: [ { 'id': 'exact', 'command': 'exact', 'client.id': 'exact', 'status': 'exact', 'jobId': 'exact' } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.trace.order:
@ -258,6 +308,11 @@ 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:
@ -292,4 +347,28 @@ 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
This is a longer description of the ogcore package.
OgCore package is responsible about management of Opengnsys platform
OpenGnsys Core is a platform for system management.

View File

@ -4,10 +4,35 @@ 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
@ -25,7 +50,8 @@ if [ "$1" = "configure" ] && [ -z "$2" ]; then
# Configuración inicial
echo ">>> Configurando base de datos y permisos"
mariadb -e "GRANT ALL ON *.* to 'root'@'localhost' IDENTIFIED BY 'root' WITH GRANT OPTION;"
mariadb -e "ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket OR mysql_native_password USING PASSWORD('root');"
echo ">>> Creando par de claves para JWT"
php bin/console lexik:jwt:generate-keypair --overwrite
@ -42,6 +68,7 @@ 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
@ -53,29 +80,31 @@ 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
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"
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" \
@ -83,29 +112,48 @@ 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"
cd /opt/opengnsys/ogcore/api
# 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"
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
[ ! -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
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,6 +2,19 @@
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"
@ -12,4 +25,18 @@ else
useradd -m -d "$HOME_DIR" -s /bin/bash "$USER"
fi
exit 0
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

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 dump-env prod
composer install --no-dev --no-interaction --no-progress --optimize-autoloader
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

View File

@ -26,7 +26,8 @@ services:
- 8443:443 # Añadir el puerto 443
volumes:
- ./public:/var/www/html/public:cached
- ./docker/certs:/etc/nginx/certs # Montar certificados en Nginx
- ./docker/certs:/etc/nginx/certs
- ./certs:/opt/opengnsys/ogcore/etc/certificates
networks:
- ogcore-network
@ -37,6 +38,7 @@ 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,6 +44,9 @@ 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,12 +1,15 @@
{
"vars": {
"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",
"OG_DHCP_API_URL": "127.0.0.1:8081",
"OG_CORE_IP": "127.0.0.1",
"OG_LOG_IP": "127.0.0.1",
"UDS_AUTH_LOGIN": "test",
"UDS_AUTH_USERNAME": "test",
"UDS_AUTH_PASSWORD": "test",
"UDS_URL": "https:\/\/localhost:8087\/uds\/rest\/"
"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"
}
}

View File

@ -0,0 +1,3 @@
*/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=":3000"
SERVER_NAME=":3001"
MERCURE_PUBLISHER_JWT_KEY="!ChangeThisMercureHubJWTSecretKey!"
MERCURE_SUBSCRIBER_JWT_KEY="!ChangeThisMercureHubJWTSecretKey!"
MERCURE_EXTRA_DIRECTIVES="cors_origins *"

View File

@ -0,0 +1,23 @@
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,6 +7,16 @@ 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;
@ -31,21 +41,6 @@ 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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,33 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,35 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,35 @@
<?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

@ -0,0 +1,33 @@
<?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

@ -0,0 +1,45 @@
<?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

@ -0,0 +1,37 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,33 @@
<?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

@ -0,0 +1,35 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,33 @@
<?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

@ -0,0 +1,33 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,39 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,31 @@
<?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

@ -0,0 +1,33 @@
<?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

@ -0,0 +1,37 @@
<?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

@ -0,0 +1,35 @@
<?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

@ -0,0 +1,37 @@
<?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)');
}
}

0
ogagent.conf 100644
View File

View File

@ -0,0 +1,100 @@
<?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

@ -4,9 +4,7 @@ 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;
@ -14,31 +12,38 @@ 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:test', description: 'Hello PhpStorm')]
class TestCommand extends Command
#[AsCommand(name: 'opengnsys:execute-pending-traces', description: 'Execute pending traces')]
class ExecutePendingTracesCommand 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);
$trace = $this->entityManager->getRepository(Trace::class)->find(7236);
$startTime = microtime(true);
$trace->setStatus(TraceStatus::SUCCESS);
$trace->setProgress(1000);
$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);
}
$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

@ -20,6 +20,8 @@ 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
)
@ -37,6 +39,7 @@ 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

@ -0,0 +1,89 @@
<?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

@ -0,0 +1,54 @@
<?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

@ -0,0 +1,35 @@
<?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,7 +2,9 @@
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;
@ -10,29 +12,44 @@ 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 ClientRepository $clientRepository,
private readonly EntityManagerInterface $entityManager
private readonly EntityManagerInterface $entityManager,
private PostAction $postAction,
)
{
}
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(ChangeOrganizationalUnitInput $input): JsonResponse
{
foreach ($input->clients as $client) {
/** @var Client $client */
$clientEntity = $this->clientRepository->find($client->getEntity()->getId());
if (!$clientEntity) {
throw new NotFoundHttpException('Client not found');
}
/** @var Client $clientEntity */
$clientEntity = $client->getEntity();
$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

@ -0,0 +1,98 @@
<?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,6 +8,7 @@ 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;
@ -31,11 +32,10 @@ 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,89 +47,149 @@ class DeployImageAction extends AbstractController
{
$this->validator->validate($input);
switch ($input->method){
$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) {
case DeployMethodTypes::UNICAST:
case DeployMethodTypes::UNICAST_DIRECT:
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;
$clientJobs = $this->handleUnicastDeployment($input, $image);
break;
case DeployMethodTypes::MULTICAST_UFTP:
case DeployMethodTypes::MULTICAST_UFTP_DIRECT:
case DeployMethodTypes::MULTICAST_UDPCAST:
case DeployMethodTypes::MULTICAST_UDPCAST_DIRECT:
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,
];
try {
$this->deployImageOgRepositoryAction->__invoke($input, $image, $client->getEntity(), $this->httpClient);
} catch (\Exception $e) {
continue;
}
$agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client->getEntity(), DeployMethodTypes::MULTICAST);
if (!$agentJobId){
continue;
}
$this->createService->__invoke($client->getEntity(), CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
}
break;
$clientJobs = $this->handleMulticastDeployment($input, $image);
break;
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);
}
$clientJobs = $this->handleTorrentDeployment($input, $image);
break;
}
return new JsonResponse(data: [], status: Response::HTTP_OK);
return $clientJobs;
}
private function handleUnicastDeployment(DeployImageInput $input, ImageImageRepository $image): array
{
$clientJobs = [];
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'] ?? ''));
}
} catch (\Exception $e) {
throw $e;
}
$jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::TORRENT);
if ($jobId) {
$clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId;
}
}
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,
]);
}
}

View File

@ -0,0 +1,87 @@
<?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,10 +4,14 @@ 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;
@ -21,6 +25,7 @@ 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,15 +34,57 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class CreateImageAction extends AbstractController
class CreateImageAction extends AbstractOgAgentController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
/**
* @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
{
$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);
}
}
/**
@ -46,29 +93,30 @@ class CreateImageAction extends AbstractController
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(Image $image): JsonResponse
public function createMonolithicImage(
ImageImageRepository $imageImageRepository,
array $partitionInfo,
Image $image,
ImageRepository $repository,
?Client $client = null,
bool $queue = false
): JsonResponse
{
if (!$image->getClient()->getIp()) {
throw new ValidatorException('IP is required');
if (!isset($partitionInfo['numDisk'], $partitionInfo['numPartition'], $partitionInfo['partitionCode'], $partitionInfo['filesystem'])) {
throw new BadRequestHttpException('Missing required partition information');
}
$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);
$client = $client ?? $image->getClient();
if (!$client->getIp() || !$client->getToken()) {
throw new BadRequestHttpException('Client IP or token is missing');
}
$data = [
'dsk' => (string) $partitionInfo['numDisk'],
'par' => (string) $partitionInfo['numPartition'],
'cpt' => null,
'idi' => $imageImageRepository->getUuid(),
'nci' => $image->getName(),
'nci' => $image->getName().'_v'.$imageImageRepository->getVersion(),
'ipr' => $repository->getIp(),
'nfn' => 'CrearImagen',
'ids' => '0'
@ -85,38 +133,219 @@ class CreateImageAction extends AbstractController
$data['cpt'] = dechex($partitionTypeCode);
} else {
throw new Exception("El tipo de partición '$partitionCode' no se encontró en la lista.");
throw new BadRequestHttpException("Invalid partition code: {$partitionCode}");
}
$this->logger->info('Creating image', ['image' => $image->getId()]);
try {
$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',
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/CrearImagen',
params: [
'json' => $data,
],
'json' => $data,
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()
]);
} 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
);
}
}
$jobId = json_decode($response->getContent(), true)['job_id'];
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');
}
$client = $image->getClient();
$client->setStatus(ClientStatus::BUSY);
$this->entityManager->persist($client);
$this->entityManager->flush();
if (!$client->getIp() || !$client->getToken()) {
throw new BadRequestHttpException('Client IP or token is missing');
}
$this->createService->__invoke($image->getClient(), CommandTypes::CREATE_IMAGE, TraceStatus::IN_PROGRESS, $jobId, []);
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'
];
return new JsonResponse(data: $image, status: Response::HTTP_OK);
$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
);
}
}
}

View File

@ -0,0 +1,91 @@
<?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,6 +21,7 @@ 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,29 +30,24 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class DeployImageAction extends AbstractController
class DeployImageAction extends AbstractOgAgentController
{
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)
public function __invoke(ImageImageRepository $imageImageRepository, DeployImageInput $input, Client $client, ?string $method = null)
{
$image = $imageImageRepository->getImage();
if (!$client->getIp()) {
throw new ValidatorException('IP is required');
throw new BadRequestHttpException('IP is required');
}
if ($input->type === 'git') {
throw new BadRequestHttpException('Use DeployGitImageAction for Git images');
}
$method = match ($input->method) {
@ -60,7 +56,7 @@ class DeployImageAction extends AbstractController
DeployMethodTypes::UNICAST_DIRECT => 'unicast-direct',
DeployMethodTypes::UNICAST => 'unicast',
DeployMethodTypes::TORRENT => 'torrent',
default => throw new ValidatorException('Invalid method'),
default => throw new BadRequestHttpException('Invalid method'),
};
$mcastMode = $input->mcastMode.'-duplex';
@ -74,7 +70,7 @@ class DeployImageAction extends AbstractController
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 ValidatorException('Invalid method'),
default => throw new BadRequestHttpException('Invalid method'),
};
$repository = $imageImageRepository->getRepository();
@ -84,33 +80,35 @@ class DeployImageAction extends AbstractController
'par' => (string) $input->partitionNumber,
'ifs' => "1",
'idi' => $image->getUuid(),
'nci' => $image->getName(),
'nci' => $imageImageRepository->getName(),
'ipr' => $repository->getIp(),
'nfn' => 'RestaurarImagen',
'ptc' => $ptcValue,
'ids' => '0'
];
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,
]);
$this->logger->info('Deploying image', ['image' => $image->getId()]);
$url = 'https://'.$client->getIp().':8000/opengnsys/RestaurarImagen';
$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;
$response = $this->createRequest(
method: 'POST',
url: $url,
params: [
'json' => $data,
],
token: $client->getToken(),
);
$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 = $response['job_id'];
$client->setStatus(ClientStatus::BUSY);
$this->entityManager->persist($client);

View File

@ -0,0 +1,57 @@
<?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

@ -0,0 +1,71 @@
<?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

@ -0,0 +1,94 @@
<?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,6 +20,7 @@ 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,26 +29,26 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class PartitionAssistantAction extends AbstractController
class PartitionAssistantAction extends AbstractOgAgentController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
{
}
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(PartitionPostInput $input): JsonResponse
{
$partitions = $input->partitions;
if (empty($partitions)) {
throw new ValidatorException('Partitions is required');
throw new BadRequestHttpException('Partitions is required');
}
$clientJobs = [];
foreach ($input->clients as $clientInput) {
/** @var Client $client */
$client = $clientInput->getEntity();
$disks = [];
@ -72,13 +73,10 @@ class PartitionAssistantAction extends AbstractController
];
}
if ($partition->filesystem === 'CACHE') {
$disks[$diskNumber]['diskData'] = [
'dis' => (string) $diskNumber,
'che' => "0",
'tch' => (string) ($partition->size * 1024),
];
}
$disks[$diskNumber]['diskData'] = [
'dis' => (string) $diskNumber,
'tch' => (string) ($partition->size * 1024),
];
$disks[$diskNumber]['partitionData'][] = [
'par' => (string) $partition->partitionNumber,
@ -103,32 +101,38 @@ class PartitionAssistantAction extends AbstractController
"ids" => "0"
];
try {
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/CloningEngine/Configurar', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/Configurar',
params: [
'json' => $result,
]);
$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()]);
],
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;
}
continue;
}
$jobId = json_decode($response->getContent(), true)['job_id'];
$jobId = $response['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, []);
$this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::IN_PROGRESS, $jobId, $data);
$clientJobs['/clients/' . $client->getUuid()] = $jobId;
}
}
return new JsonResponse(data: [], status: Response::HTTP_OK);
return new JsonResponse(data: $clientJobs, status: Response::HTTP_OK);
}
}

View File

@ -20,6 +20,7 @@ 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;
@ -28,17 +29,14 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class PowerOffAction extends AbstractController
class PowerOffAction extends AbstractOgAgentController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
{
}
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(MultipleClientsInput $input): JsonResponse
{
foreach ($input->clients as $clientEntity) {
@ -46,10 +44,10 @@ class PowerOffAction extends AbstractController
$client = $clientEntity->getEntity();
if (!$client->getIp()) {
throw new ValidatorException('IP is required');
throw new BadRequestHttpException('IP is required');
}
if ($client->getStatus() === ClientStatus::OFF) {
if ($client->getStatus() === ClientStatus::OFF || $client->getStatus() === ClientStatus::TURNING_OFF || $client->getStatus() === ClientStatus::DISCONNECTED) {
continue;
}
@ -58,26 +56,30 @@ class PowerOffAction extends AbstractController
'ids' => '0'
];
try {
$response = $this->httpClient->request('POST', 'https://'.$client->getIp().':8000/ogAdmClient/Apagar', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/Apagar',
params: [
'json' => $data,
]);
$this->logger->info('Powering off client', ['client' => $client->getId()]);
$jobId = json_decode($response->getContent(), true)['job_id'];
],
token: $client->getToken(),
);
} catch (ClientExceptionInterface | ServerExceptionInterface | TransportExceptionInterface | TransportException $e) {
$this->logger->error('Error power off client', [
'image' => $client->getIp(),
'error' => $e->getMessage()
]);
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;
}
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,6 +19,7 @@ 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;
@ -27,25 +28,23 @@ use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class RebootAction extends AbstractController
class RebootAction extends AbstractOgAgentController
{
public function __construct(
protected readonly EntityManagerInterface $entityManager,
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
)
{
}
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(MultipleClientsInput $input): JsonResponse
{
foreach ($input->clients as $clientEntity) {
/** @var Client $client */
$client = $clientEntity->getEntity();
if (!$client->getIp()) {
throw new ValidatorException('IP is required');
throw new BadRequestHttpException('IP is required');
}
$data = [
@ -53,26 +52,27 @@ class RebootAction extends AbstractController
'ids' => '0'
];
try {
$response = $this->httpClient->request('POST', 'https://' . $client->getIp() . ':8000/ogAdmClient/Reiniciar', [
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'Content-Type' => 'application/json',
],
$response = $this->createRequest(
method: 'POST',
url: 'https://'.$client->getIp().':8000/opengnsys/Reiniciar',
params: [
'json' => $data,
]);
$this->logger->info('Rebooting client', ['client' => $client->getId()]);
],
token: $client->getToken(),
);
} 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
);
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;
}
$jobId = json_decode($response->getContent(), true)['job_id'];
$this->logger->info('Rebooting client', ['client' => $client->getId()]);
$jobId = $response['job_id'];
$client->setStatus(ClientStatus::INITIALIZING);
$this->entityManager->persist($client);

View File

@ -0,0 +1,91 @@
<?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

@ -0,0 +1,93 @@
<?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

@ -0,0 +1,62 @@
<?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