From 1d713450e89d149b879e2bad30de80a21b42d382 Mon Sep 17 00:00:00 2001 From: "mtarrade.sap@gmail.com" Date: Fri, 20 Dec 2024 09:50:28 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84add=20status=20in=20global=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controlpanel/api/models/Config-data.js | 4 ++++ controlpanel/api/routes/configmanager.js | 10 +++----- controlpanel/api/services/configmanager.js | 14 +++++------ .../cad/src/app/models/config-data.ts | 1 + .../app/pages/config/config.component.html | 7 +++++- .../app/pages/config/config.component.scss | 24 +++++++++++++++++++ .../src/app/pages/config/config.component.ts | 22 +++++++++++++---- .../services/api/configmanager-api.service.ts | 13 ++-------- 8 files changed, 65 insertions(+), 30 deletions(-) diff --git a/controlpanel/api/models/Config-data.js b/controlpanel/api/models/Config-data.js index 8ba84df..5b5f3a1 100644 --- a/controlpanel/api/models/Config-data.js +++ b/controlpanel/api/models/Config-data.js @@ -16,6 +16,10 @@ const Config = sequelize.define("config", { }, allowNull: false }, + deployed: { + type: DataTypes.BOOLEAN, + allowNull: false + }, config: { type: DataTypes.JSON, allowNull: false diff --git a/controlpanel/api/routes/configmanager.js b/controlpanel/api/routes/configmanager.js index 18ab0b8..9df61de 100644 --- a/controlpanel/api/routes/configmanager.js +++ b/controlpanel/api/routes/configmanager.js @@ -28,20 +28,16 @@ router.get('/config/:namespace/:application', async (req, res) => { try { const { namespace, application } = req.params; const result = await configmanagerService.getConfig(namespace, application); - if (result.type == 'error') { - return res.status(500).send(result.data); - } - return res.status(200).send(result.data); + return res.status(result.code).send(result); } catch (e) { console.error(e); return res.status(500).send("Server error"); } }); -router.put('/config/:namespace/:application', async (req, res) => { +router.put('/config/:pa_id', async (req, res) => { try { - const { namespace, application } = req.params; - const result = await configmanagerService.updateConfig(namespace, application, req.body); + const result = await configmanagerService.updateConfig(req.params.pa_id); return res.status(result.code).send(result); } catch (e) { console.error(e); diff --git a/controlpanel/api/services/configmanager.js b/controlpanel/api/services/configmanager.js index 84da066..a3499da 100644 --- a/controlpanel/api/services/configmanager.js +++ b/controlpanel/api/services/configmanager.js @@ -89,14 +89,14 @@ module.exports = { * @param {Object} config * @return {{type: 'success' | 'error' | 'warning', code: number, data: JSON, message: string}} */ - updateConfig: async (namespace, application, config) => { + updateConfig: async (pa_id) => { try { - if (!namespace || !application) { - namespace = 'unknown'; - application = 'unknown'; - } - if (validateConfig(config).length) return { type: 'error', code: 422, message: "There are errors in the global config, cannot send to configmanager" }; - const response = await axios.post(`${CONFIGMANAGER_URL}/${namespace}/${application}`,{ config }); + const protectedApp = await ProtectedApp.findByPk(pa_id); + if (!protectedApp || !isUUID(pa_id)) return { type: 'error', code: 400, message: 'Invalid protectedApp id provided' }; + const config = await Config.update({ deployed: true }, { where: { pa_id }, returning: true }); + if (!config[1].length) return { type: 'warning', code: 200, message: "Global config is empty or not saved, cannot sync" }; + if (validateConfig(config[1][0].config).length) return { type: 'error', code: 422, message: "There are errors in the global config, cannot send to configmanager" }; + const response = await axios.post(`${CONFIGMANAGER_URL}/${protectedApp.namespace}/${protectedApp.application}`,{ config: config[1][0].config }); if (response.status != 200) { if (response.data && response.data.config) { return { type: 'error', code: 404, message: 'No file found' }; diff --git a/controlpanel/cad/src/app/models/config-data.ts b/controlpanel/cad/src/app/models/config-data.ts index ebe10f4..4efb126 100644 --- a/controlpanel/cad/src/app/models/config-data.ts +++ b/controlpanel/cad/src/app/models/config-data.ts @@ -4,5 +4,6 @@ import { UUID } from "./types"; export interface ConfigData { id?: UUID, pa_id: UUID + deployed: boolean config: Config } \ No newline at end of file diff --git a/controlpanel/cad/src/app/pages/config/config.component.html b/controlpanel/cad/src/app/pages/config/config.component.html index b239f9f..e9fadbd 100644 --- a/controlpanel/cad/src/app/pages/config/config.component.html +++ b/controlpanel/cad/src/app/pages/config/config.component.html @@ -9,7 +9,12 @@

Config 🔧

- +
+
+
+

{{ isSync ? 'Sync' : 'Not sync' }}

+
+
diff --git a/controlpanel/cad/src/app/pages/config/config.component.scss b/controlpanel/cad/src/app/pages/config/config.component.scss index 3307afb..5aeee87 100644 --- a/controlpanel/cad/src/app/pages/config/config.component.scss +++ b/controlpanel/cad/src/app/pages/config/config.component.scss @@ -1,3 +1,27 @@ +.top-bar { + display: flex; + flex-direction: row; + margin-bottom: 1rem; + .right { + margin-left: auto; + margin-right: 2rem; + display: flex; + align-items: center; + .status-true { + mask: url('../../../../public/check.svg') no-repeat center; + width: 24px; + height: 24px; + background-color: green; + } + .status-false { + mask: url('../../../../public/close_small.svg') no-repeat center; + width: 24px; + height: 24px; + background-color: red; + } + } +} + .config-form { display: flex; flex-direction: row; diff --git a/controlpanel/cad/src/app/pages/config/config.component.ts b/controlpanel/cad/src/app/pages/config/config.component.ts index 7408941..f0c159d 100644 --- a/controlpanel/cad/src/app/pages/config/config.component.ts +++ b/controlpanel/cad/src/app/pages/config/config.component.ts @@ -13,6 +13,7 @@ import { GlobalStateService } from '../../services/global-state.service'; import { ToastrService } from 'ngx-toastr'; import { isEmptyObject } from '../../utils'; import { ConfigmanagerApiService } from '../../services/api/configmanager-api.service'; +import { ConfigData } from '../../models/config-data'; @Component({ selector: 'app-config', @@ -27,6 +28,7 @@ export class ConfigComponent implements OnInit, OnDestroy { config: Config = {}; configSubscription?: Subscription isUpdating = false; + isSync = false; validRespond = false; actionTouched = false; @@ -82,6 +84,8 @@ onLeaveInfo() { this.fillForm({}); this.config = {}; this.actionArray = []; + } else { + this.isSync = (apiResponse.data as ConfigData).deployed } this.configSubscription = this.configService.config$.subscribe(data => { if (!this.isUpdating){ @@ -89,6 +93,7 @@ onLeaveInfo() { this.config = data; this.fillForm(this.config); this.isUpdating = false; + this.configForm.valueChanges.subscribe(() => this.isSync = false) } }) }) @@ -273,14 +278,23 @@ onLeaveInfo() { this.toastr.error("Cannot save empty json, must have at least one property", 'Error when saving global config'); return } - const apiResponse = await this.configService.updateConfig({ pa_id: this.globalState.selectedApp.id, config: this.config }); + const apiResponse = await this.configService.updateConfig({ pa_id: this.globalState.selectedApp.id, deployed: false, config: this.config }); if (apiResponse.type == 'error') this.toastr.error(apiResponse.message, "Error when saving global config"); - else this.toastr.success(apiResponse.message, 'Successfully updated global config'); + else { + this.toastr.success(apiResponse.message, 'Successfully updated global config'); + this.isSync = false; + } } async sync() { - const saveResponse = await this.configmanagerApi.updateConfigmanagerConfig(this.globalState.selectedApp.namespace, this.globalState.selectedApp.application, this.config) + const apiResponse = await this.configService.updateConfig({ pa_id: this.globalState.selectedApp.id, deployed: false, config: this.config }); + if (apiResponse.type == 'error') this.toastr.error(apiResponse.message, "Error when saving global config"); + const saveResponse = await this.configmanagerApi.updateConfigmanagerConfig(this.globalState.selectedApp.id) if (saveResponse.type == 'error') this.toastr.error(saveResponse.message, "Error Synchronizing"); else if (saveResponse.type == 'warning') this.toastr.warning(saveResponse.message, "Warning"); - else this.toastr.success("Successfully synchronized with configmanager", "Synchronized"); + else { + this.toastr.success("Successfully synchronized with configmanager", "Synchronized"); + const apiResponse = await this.configService.getConfig(this.globalState.selectedApp.id) + this.isSync = (apiResponse.data as ConfigData).deployed + } } } diff --git a/controlpanel/cad/src/app/services/api/configmanager-api.service.ts b/controlpanel/cad/src/app/services/api/configmanager-api.service.ts index 96cab6d..fa79528 100644 --- a/controlpanel/cad/src/app/services/api/configmanager-api.service.ts +++ b/controlpanel/cad/src/app/services/api/configmanager-api.service.ts @@ -21,21 +21,12 @@ export class ConfigmanagerApiService { return { message: 'Cannot synchronize decoys with configmanager', type: 'error' }; } } - async updateConfigmanagerConfig(namespace: string, application: string, config: Config) { + async updateConfigmanagerConfig(pa_id: UUID) { try { - return await lastValueFrom(this.http.put(`${this.globalState.API_URL}/configmanager/config/${namespace}/${application}`, config)); + return await lastValueFrom(this.http.put(`${this.globalState.API_URL}/configmanager/config/${pa_id}`, '')); } catch (e) { console.error(e); return { message: 'Cannot synchronize config with configmanager', type: 'error' }; } } - async getConfigmanagerDecoys(namespace: string, application: string) { - try { - return await lastValueFrom(this.http.get(`${this.globalState.API_URL}/configmanager/decoys/${namespace}/${application}`)); - } catch (e) { - console.error(e); - return { message: 'Cannot synchronize config with configmanager', type: 'error' }; - } - } - }