@centreon/js-config 24.10.3 → 24.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/biome/base.json +224 -0
  2. package/cypress/component/commands.tsx +82 -22
  3. package/cypress/component/configuration.js +39 -16
  4. package/cypress/component/disableCssTransitions.ts +19 -0
  5. package/cypress/component/enableVisualTesting.ts +1 -1
  6. package/cypress/component/excludeNodeModulesFromCoverage.js +36 -0
  7. package/cypress/e2e/commands/configuration.ts +330 -1
  8. package/cypress/e2e/commands/monitoring.ts +225 -0
  9. package/cypress/e2e/commands.ts +727 -174
  10. package/cypress/e2e/configuration.ts +46 -40
  11. package/cypress/e2e/esbuild-preprocessor.ts +26 -0
  12. package/cypress/e2e/plugins.ts +52 -114
  13. package/cypress/e2e/reporter-config.js +13 -0
  14. package/cypress/e2e/tasks.ts +259 -0
  15. package/eslint/base.typescript.eslintrc.js +15 -3
  16. package/eslint/lambda/typescript.eslintrc.js +48 -0
  17. package/jest/index.js +5 -2
  18. package/jest/lambda/typescript.js +49 -0
  19. package/package.json +57 -45
  20. package/rspack/base/globalConfig.js +71 -0
  21. package/rspack/base/index.js +89 -0
  22. package/rspack/patch/dev.js +12 -0
  23. package/{webpack → rspack}/patch/devServer.js +4 -8
  24. package/rspack/patch/module.js +13 -0
  25. package/rspack/plugins/TransformPreloadScript.js +37 -0
  26. package/rspack/plugins/WriteRemoteEntryNameToModuleFederation.js +30 -0
  27. package/tsconfig/index.json +5 -4
  28. package/tsconfig/lambda/node20.tsconfig.json +12 -0
  29. package/tsconfig/lambda/tsconfig.json +14 -0
  30. package/tsconfig.json +21 -0
  31. package/webpack/base/index.js +0 -130
  32. package/webpack/patch/dev.js +0 -24
  33. package/webpack/patch/module.js +0 -46
@@ -1,5 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-namespace */
2
2
 
3
+ import { Action } from 'e2e/features/ACLs/commands';
4
+
3
5
  const apiBase = '/centreon/api';
4
6
  const apiActionV1 = `${apiBase}/index.php`;
5
7
 
@@ -138,12 +140,109 @@ Cypress.Commands.add(
138
140
  }
139
141
  );
140
142
 
143
+ interface Contact {
144
+ GUIAccess?: boolean;
145
+ admin?: boolean;
146
+ alias?: string | null;
147
+ authenticationType?: 'local' | 'ldap';
148
+ email: string;
149
+ enableNotifications?: boolean;
150
+ language?: string;
151
+ name: string;
152
+ password: string;
153
+ }
154
+
155
+ Cypress.Commands.add(
156
+ 'addContact',
157
+ ({
158
+ admin = true,
159
+ alias = null,
160
+ authenticationType = 'local',
161
+ email,
162
+ enableNotifications = true,
163
+ GUIAccess = true,
164
+ language = 'en_US',
165
+ name,
166
+ password
167
+ }: Contact): Cypress.Chainable => {
168
+ const contactAdmin = admin ? 1 : 0;
169
+ const contactAlias = alias === null ? name : alias;
170
+ const contactEnableNotifications = enableNotifications ? 1 : 0;
171
+ const contactGUIAccess = GUIAccess ? 1 : 0;
172
+
173
+ return cy
174
+ .executeActionViaClapi({
175
+ bodyContent: {
176
+ action: 'ADD',
177
+ object: 'CONTACT',
178
+ values: `${name};${contactAlias};${email};${password};${contactAdmin};${contactGUIAccess};${language};${authenticationType}`
179
+ }
180
+ })
181
+ .then(() => {
182
+ const contactParams = {
183
+ enable_notifications: contactEnableNotifications
184
+ };
185
+ Object.entries(contactParams).map(([paramName, paramValue]) => {
186
+ if (paramValue === null) {
187
+ return null;
188
+ }
189
+
190
+ return cy.executeActionViaClapi({
191
+ bodyContent: {
192
+ action: 'SETPARAM',
193
+ object: 'CONTACT',
194
+ values: `${name};${paramName};${paramValue}`
195
+ }
196
+ });
197
+ });
198
+
199
+ return cy.wrap(null);
200
+ });
201
+ }
202
+ );
203
+
204
+ interface ContactGroup {
205
+ alias?: string | null;
206
+ contacts: Array<string>;
207
+ name: string;
208
+ }
209
+
210
+ Cypress.Commands.add(
211
+ 'addContactGroup',
212
+ ({ alias = null, contacts, name }: ContactGroup): Cypress.Chainable => {
213
+ const contactGroupAlias = alias === null ? name : alias;
214
+
215
+ return cy
216
+ .executeActionViaClapi({
217
+ bodyContent: {
218
+ action: 'ADD',
219
+ object: 'CG',
220
+ values: `${name};${contactGroupAlias}`
221
+ }
222
+ })
223
+ .then(() => {
224
+ contacts.map((contact) => {
225
+ return cy.executeActionViaClapi({
226
+ bodyContent: {
227
+ action: 'ADDCONTACT',
228
+ object: 'CG',
229
+ values: `${name};${contact}`
230
+ }
231
+ });
232
+ });
233
+
234
+ return cy.wrap(null);
235
+ });
236
+ }
237
+ );
238
+
141
239
  interface Host {
142
240
  activeCheckEnabled?: boolean;
143
241
  address?: string;
144
242
  alias?: string | null;
145
243
  checkCommand?: string | null;
146
244
  checkPeriod?: string | null;
245
+ hostGroup?: string;
147
246
  maxCheckAttempts?: number | null;
148
247
  name: string;
149
248
  passiveCheckEnabled?: boolean;
@@ -159,6 +258,7 @@ Cypress.Commands.add(
159
258
  alias = null,
160
259
  checkCommand = null,
161
260
  checkPeriod = null,
261
+ hostGroup = '',
162
262
  maxCheckAttempts = 1,
163
263
  name,
164
264
  passiveCheckEnabled = true,
@@ -176,7 +276,7 @@ Cypress.Commands.add(
176
276
  bodyContent: {
177
277
  action: 'ADD',
178
278
  object: 'HOST',
179
- values: `${name};${hostAlias};${address};${template};${poller};`
279
+ values: `${name};${hostAlias};${address};${template};${poller};${hostGroup}`
180
280
  }
181
281
  })
182
282
  .then(() => {
@@ -206,6 +306,26 @@ Cypress.Commands.add(
206
306
  }
207
307
  );
208
308
 
309
+ interface HostGroup {
310
+ alias?: string | null;
311
+ name: string;
312
+ }
313
+
314
+ Cypress.Commands.add(
315
+ 'addHostGroup',
316
+ ({ alias = null, name }: HostGroup): Cypress.Chainable => {
317
+ const hostGroupAlias = alias === null ? name : alias;
318
+
319
+ return cy.executeActionViaClapi({
320
+ bodyContent: {
321
+ action: 'ADD',
322
+ object: 'HG',
323
+ values: `${name};${hostGroupAlias}`
324
+ }
325
+ });
326
+ }
327
+ );
328
+
209
329
  interface ServiceTemplate {
210
330
  activeCheckEnabled?: boolean;
211
331
  checkCommand?: string | null;
@@ -327,6 +447,45 @@ Cypress.Commands.add(
327
447
  }
328
448
  );
329
449
 
450
+ interface ServiceGroup {
451
+ alias?: string | null;
452
+ hostsAndServices: Array<Array<string>>;
453
+ name: string;
454
+ }
455
+
456
+ Cypress.Commands.add(
457
+ 'addServiceGroup',
458
+ ({
459
+ alias = null,
460
+ hostsAndServices,
461
+ name
462
+ }: ServiceGroup): Cypress.Chainable => {
463
+ const serviceGroupAlias = alias === null ? name : alias;
464
+
465
+ return cy
466
+ .executeActionViaClapi({
467
+ bodyContent: {
468
+ action: 'ADD',
469
+ object: 'SG',
470
+ values: `${name};${serviceGroupAlias}`
471
+ }
472
+ })
473
+ .then(() => {
474
+ hostsAndServices.map((hostAndService) => {
475
+ return cy.executeActionViaClapi({
476
+ bodyContent: {
477
+ action: 'ADDSERVICE',
478
+ object: 'SG',
479
+ values: `${name};${hostAndService[0]},${hostAndService[1]}`
480
+ }
481
+ });
482
+ });
483
+
484
+ return cy.wrap(null);
485
+ });
486
+ }
487
+ );
488
+
330
489
  Cypress.Commands.add(
331
490
  'applyPollerConfiguration',
332
491
  (pollerName = 'Central'): Cypress.Chainable => {
@@ -339,12 +498,182 @@ Cypress.Commands.add(
339
498
  }
340
499
  );
341
500
 
501
+ interface ACLGroup {
502
+ alias?: string | null;
503
+ contactGroups?: Array<string>;
504
+ contacts?: Array<string>;
505
+ name: string;
506
+ }
507
+
508
+ Cypress.Commands.add(
509
+ 'addACLGroup',
510
+ ({
511
+ alias = null,
512
+ contacts = [],
513
+ contactGroups = [],
514
+ name
515
+ }: ACLGroup): Cypress.Chainable => {
516
+ const ACLGroupALias = alias === null ? name : alias;
517
+
518
+ return cy
519
+ .executeActionViaClapi({
520
+ bodyContent: {
521
+ action: 'ADD',
522
+ object: 'ACLGROUP',
523
+ values: `${name};${ACLGroupALias}`
524
+ }
525
+ })
526
+ .then(() => {
527
+ if (contacts) {
528
+ contacts.forEach((contact) => {
529
+ cy.executeActionViaClapi({
530
+ bodyContent: {
531
+ action: 'ADDCONTACT',
532
+ object: 'ACLGROUP',
533
+ values: `${name};${contact}`
534
+ }
535
+ });
536
+ });
537
+ }
538
+ if (contactGroups) {
539
+ contactGroups.forEach((contactGroup) => {
540
+ cy.executeActionViaClapi({
541
+ bodyContent: {
542
+ action: 'ADDCONTACTGROUP',
543
+ object: 'ACLGROUP',
544
+ values: `${name};${contactGroup}`
545
+ }
546
+ });
547
+ });
548
+ }
549
+ });
550
+ }
551
+ );
552
+
553
+ interface ACLMenu {
554
+ alias?: string | null;
555
+ includeChildren?: boolean;
556
+ name: string;
557
+ readOnly?: boolean;
558
+ rule?: Array<string>;
559
+ }
560
+
561
+ Cypress.Commands.add(
562
+ 'addACLMenu',
563
+ ({
564
+ name,
565
+ rule = [],
566
+ alias = null,
567
+ includeChildren = true,
568
+ readOnly = false
569
+ }: ACLMenu): Cypress.Chainable => {
570
+ const ACLMenuAlias = alias === null ? name : alias;
571
+ const action = readOnly ? 'GRANTRO' : 'GRANTRW';
572
+ const children = includeChildren ? '1' : '0';
573
+
574
+ return cy
575
+ .executeActionViaClapi({
576
+ bodyContent: {
577
+ action: 'ADD',
578
+ object: 'ACLMENU',
579
+ values: `${name};${ACLMenuAlias}`
580
+ }
581
+ })
582
+ .then(() => {
583
+ if (rule.length === 0) {
584
+ return cy.wrap(null);
585
+ }
586
+
587
+ let ruleCommand = '';
588
+ rule.forEach((rulePage, index) => {
589
+ ruleCommand += rulePage + (index == rule.length - 1 ? '' : ';');
590
+ });
591
+ cy.executeActionViaClapi({
592
+ bodyContent: {
593
+ action,
594
+ object: 'ACLMENU',
595
+ values: `${name};${children};${ruleCommand}`
596
+ }
597
+ });
598
+
599
+ return cy.wrap(null);
600
+ });
601
+ }
602
+ );
603
+
604
+ interface ACLAction {
605
+ actions?: Array<Action>;
606
+ description: string;
607
+ name: string;
608
+ }
609
+
610
+ Cypress.Commands.add(
611
+ 'addACLAction',
612
+ ({ name, description, actions = [] }: ACLAction): Cypress.Chainable => {
613
+ return cy
614
+ .executeActionViaClapi({
615
+ bodyContent: {
616
+ action: 'ADD',
617
+ object: 'ACLACTION',
618
+ values: `${name};${description}`
619
+ }
620
+ })
621
+ .then(() => {
622
+ if (actions.length === 0) {
623
+ return cy.wrap(null);
624
+ }
625
+
626
+ let actionCommand = '';
627
+ actions.forEach((action, index) => {
628
+ actionCommand += action + (index == actions.length - 1 ? '' : '|');
629
+ });
630
+ cy.executeActionViaClapi({
631
+ bodyContent: {
632
+ action: 'GRANT',
633
+ object: 'ACLACTION',
634
+ values: `${name};${actionCommand}`
635
+ }
636
+ });
637
+
638
+ return cy.wrap(null);
639
+ });
640
+ }
641
+ );
642
+
643
+ interface ACLResource {
644
+ alias?: string | null;
645
+ name: string;
646
+ }
647
+
648
+ Cypress.Commands.add(
649
+ 'addACLResource',
650
+ ({ name, alias = null }: ACLResource): Cypress.Chainable => {
651
+ const ACLResourcesAlias = alias === null ? name : alias;
652
+
653
+ return cy.executeActionViaClapi({
654
+ bodyContent: {
655
+ action: 'ADD',
656
+ object: 'ACLRESOURCE',
657
+ values: `${name};${ACLResourcesAlias}`
658
+ }
659
+ });
660
+ }
661
+ );
662
+
342
663
  declare global {
343
664
  namespace Cypress {
344
665
  interface Chainable {
666
+ addACLAction: (props: ACLAction) => Cypress.Chainable;
667
+ addACLGroup: (props: ACLGroup) => Cypress.Chainable;
668
+ addACLMenu: (props: ACLMenu) => Cypress.Chainable;
669
+ addACLResource: (props: ACLResource) => Cypress.Chainable;
345
670
  addCheckCommand: (props: CheckCommand) => Cypress.Chainable;
671
+ addContact: (props: Contact) => Cypress.Chainable;
672
+ addContactGroup: (props: ContactGroup) => Cypress.Chainable;
346
673
  addHost: (props: Host) => Cypress.Chainable;
674
+ addHostGroup: (props: HostGroup) => Cypress.Chainable;
347
675
  addService: (props: Service) => Cypress.Chainable;
676
+ addServiceGroup: (props: ServiceGroup) => Cypress.Chainable;
348
677
  addServiceTemplate: (props: ServiceTemplate) => Cypress.Chainable;
349
678
  addTimePeriod: (props: TimePeriod) => Cypress.Chainable;
350
679
  applyPollerConfiguration: (props?: string) => Cypress.Chainable;
@@ -0,0 +1,225 @@
1
+ /* eslint-disable @typescript-eslint/no-namespace */
2
+
3
+ const apiBase = '/centreon/api';
4
+ const apiActionV1 = `${apiBase}/index.php`;
5
+
6
+ const getStatusNumberFromString = (status: string): number => {
7
+ const statuses = {
8
+ critical: '2',
9
+ down: '1',
10
+ ok: '0',
11
+ unknown: '3',
12
+ unreachable: '2',
13
+ up: '0',
14
+ warning: '1'
15
+ };
16
+
17
+ if (status in statuses) {
18
+ return statuses[status];
19
+ }
20
+
21
+ throw new Error(`Status ${status} does not exist`);
22
+ };
23
+
24
+ interface HostCheck {
25
+ host: string;
26
+ isForced?: boolean;
27
+ }
28
+
29
+ Cypress.Commands.add(
30
+ 'scheduleHostCheck',
31
+ ({
32
+ host,
33
+ isForced = true
34
+ }: ServiceCheck): Cypress.Chainable => {
35
+ let query = `SELECT id FROM resources WHERE name = '${host}' AND type = 1`;
36
+
37
+ return cy
38
+ .requestOnDatabase({
39
+ database: 'centreon_storage',
40
+ query
41
+ })
42
+ .then(([rows]) => {
43
+ if (rows.length === 0) {
44
+ throw new Error(`Cannot find host ${host}`);
45
+ }
46
+
47
+ const hostId = rows[0].id;
48
+
49
+ return cy.request({
50
+ body: {
51
+ check: {
52
+ is_forced: isForced
53
+ },
54
+ resources: [
55
+ {
56
+ id: hostId,
57
+ parent: null,
58
+ type: 'host'
59
+ }
60
+ ]
61
+ },
62
+ method: 'POST',
63
+ timeout: 30000,
64
+ url: '/centreon/api/latest/monitoring/resources/check'
65
+ }).then((response) => {
66
+ expect(response.status).to.eq(204);
67
+
68
+ return cy.wrap(null);
69
+ });
70
+ });
71
+ }
72
+ );
73
+
74
+ interface ServiceCheck {
75
+ host: string;
76
+ isForced?: boolean;
77
+ service: string;
78
+ }
79
+
80
+ Cypress.Commands.add(
81
+ 'scheduleServiceCheck',
82
+ ({
83
+ host,
84
+ isForced = true,
85
+ service
86
+ }: ServiceCheck): Cypress.Chainable => {
87
+ let query = `SELECT parent_id, id FROM resources WHERE parent_name = '${host}' AND name = '${service}'`;
88
+
89
+ return cy
90
+ .requestOnDatabase({
91
+ database: 'centreon_storage',
92
+ query
93
+ })
94
+ .then(([rows]) => {
95
+ if (rows.length === 0) {
96
+ throw new Error(`Cannot find service ${host} / ${service}`);
97
+ }
98
+
99
+ const hostId = rows[0].parent_id;
100
+ const serviceId = rows[0].id;
101
+
102
+ return cy.request({
103
+ body: {
104
+ check: {
105
+ is_forced: isForced
106
+ },
107
+ resources: [
108
+ {
109
+ id: serviceId,
110
+ parent: {
111
+ id: hostId
112
+ },
113
+ type: 'service'
114
+ }
115
+ ]
116
+ },
117
+ method: 'POST',
118
+ timeout: 30000,
119
+ url: '/centreon/api/latest/monitoring/resources/check'
120
+ }).then((response) => {
121
+ expect(response.status).to.eq(204);
122
+
123
+ return cy.wrap(null);
124
+ });
125
+ });
126
+ }
127
+ );
128
+
129
+
130
+ interface SubmitResult {
131
+ host: string;
132
+ output: string;
133
+ perfdata?: string | null;
134
+ service?: string | null;
135
+ status: string;
136
+ }
137
+
138
+ Cypress.Commands.add(
139
+ 'submitResults',
140
+ (results: Array<SubmitResult>): Cypress.Chainable => {
141
+ results.forEach(
142
+ ({ host, output, perfdata = '', service = null, status }) => {
143
+ const timestampNow = Math.floor(Date.now() / 1000) - 15;
144
+ const updatetime = timestampNow.toString();
145
+
146
+ const result = {
147
+ host,
148
+ output,
149
+ perfdata,
150
+ service,
151
+ status: getStatusNumberFromString(status),
152
+ updatetime
153
+ };
154
+
155
+ cy.request({
156
+ body: {
157
+ results: [result]
158
+ },
159
+ headers: {
160
+ 'Content-Type': 'application/json',
161
+ 'centreon-auth-token': window.localStorage.getItem('userTokenApiV1')
162
+ },
163
+ method: 'POST',
164
+ url: `${apiActionV1}?action=submit&object=centreon_submit_results`
165
+ });
166
+ }
167
+ );
168
+
169
+ return cy.wrap(null);
170
+ }
171
+ );
172
+
173
+ interface Downtime {
174
+ host: string;
175
+ service?: string | null;
176
+ }
177
+
178
+ Cypress.Commands.add(
179
+ 'waitForDowntime',
180
+ (downtime: Downtime): Cypress.Chainable => {
181
+ cy.log('Checking hosts in database');
182
+
183
+ let query = `SELECT COUNT(d.downtime_id) AS count_downtimes FROM downtimes as d
184
+ INNER JOIN hosts as h ON h.host_id = d.host_id AND h.name = '${downtime.host}'`;
185
+ if (downtime.service) {
186
+ query += ` INNER JOIN services as s ON s.service_id = d.service_id AND s.description = '${downtime.service}'`;
187
+ }
188
+ query += ` WHERE d.started=1`;
189
+ if (!downtime.service) {
190
+ query += ` AND d.service_id = 0`;
191
+ }
192
+
193
+ cy.log(query);
194
+
195
+ cy.waitUntil(() => {
196
+ return cy
197
+ .requestOnDatabase({
198
+ database: 'centreon_storage',
199
+ query
200
+ })
201
+ .then(([rows]) => {
202
+ const foundDowntimesCount = rows.length ? rows[0].count_downtimes : 0;
203
+
204
+ cy.log('Downtime count in database', foundDowntimesCount);
205
+
206
+ return cy.wrap(foundDowntimesCount > 0);
207
+ });
208
+ });
209
+
210
+ return cy.wrap(null);
211
+ }
212
+ );
213
+
214
+ declare global {
215
+ namespace Cypress {
216
+ interface Chainable {
217
+ scheduleHostCheck: (hostCheck) => Cypress.Chainable;
218
+ scheduleServiceCheck: (serviceCheck) => Cypress.Chainable;
219
+ submitResults: (props: Array<SubmitResult>) => Cypress.Chainable;
220
+ waitForDowntime: (downtime: Downtime) => Cypress.Chainable;
221
+ }
222
+ }
223
+ }
224
+
225
+ export {};