@adobe/aio-cli-plugin-api-mesh 5.2.4-alpha.0 → 5.2.4-alpha.1

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 (39) hide show
  1. package/oclif.manifest.json +1 -1
  2. package/package.json +13 -6
  3. package/src/commands/api-mesh/__tests__/cache-purge.test.js +1 -2
  4. package/src/commands/api-mesh/__tests__/create.test.js +19 -22
  5. package/src/commands/api-mesh/__tests__/delete-log-forwarding.test.js +106 -0
  6. package/src/commands/api-mesh/__tests__/delete.test.js +1 -2
  7. package/src/commands/api-mesh/__tests__/describe.test.js +1 -3
  8. package/src/commands/api-mesh/__tests__/get.test.js +2 -2
  9. package/src/commands/api-mesh/__tests__/log-get-bulk.test.js +19 -213
  10. package/src/commands/api-mesh/__tests__/run.test.js +191 -65
  11. package/src/commands/api-mesh/__tests__/update.test.js +8 -7
  12. package/src/commands/api-mesh/cache/purge.js +1 -3
  13. package/src/commands/api-mesh/config/delete/log-forwarding.js +80 -0
  14. package/src/commands/api-mesh/create.js +22 -6
  15. package/src/commands/api-mesh/delete.js +1 -3
  16. package/src/commands/api-mesh/describe.js +1 -3
  17. package/src/commands/api-mesh/get.js +1 -3
  18. package/src/commands/api-mesh/log-get-bulk.js +5 -26
  19. package/src/commands/api-mesh/log-get.js +1 -3
  20. package/src/commands/api-mesh/log-list.js +1 -3
  21. package/src/commands/api-mesh/run.js +207 -168
  22. package/src/commands/api-mesh/source/discover.js +2 -9
  23. package/src/commands/api-mesh/source/get.js +1 -8
  24. package/src/commands/api-mesh/source/install.js +1 -2
  25. package/src/commands/api-mesh/status.js +1 -2
  26. package/src/commands/api-mesh/update.js +21 -6
  27. package/src/commands/{PLUGINNAME/__tests__/index.test.js → api-mesh.js} +13 -15
  28. package/src/helpers.js +73 -15
  29. package/src/hooks/initMetadata.js +8 -0
  30. package/src/lib/smsClient.js +115 -1
  31. package/src/meshArtifact.js +231 -0
  32. package/src/project.js +56 -0
  33. package/src/server.js +74 -32
  34. package/src/utils.js +26 -24
  35. package/src/{index.js → worker.js} +9 -7
  36. package/src/wranglerCli.js +54 -0
  37. package/wrangler.toml +13 -0
  38. package/src/commands/PLUGINNAME/index.js +0 -32
  39. package/src/wranglerServer.js +0 -80
@@ -10,12 +10,7 @@ governing permissions and limitations under the License.
10
10
  */
11
11
 
12
12
  const { Command, CliUx, Flags } = require('@oclif/core');
13
- const {
14
- promptConfirm,
15
- initRequestId,
16
- promptMultiselect,
17
- promptSelect,
18
- } = require('../../../helpers');
13
+ const { promptConfirm, promptMultiselect, promptSelect } = require('../../../helpers');
19
14
  const SourceRegistryStorage = require('source-registry-storage-adapter');
20
15
  const config = require('@adobe/aio-lib-core-config');
21
16
  const logger = require('../../../classes/logger');
@@ -24,8 +19,6 @@ const InstallCommand = require('./install');
24
19
  class DiscoverCommand extends Command {
25
20
  async run() {
26
21
  try {
27
- await initRequestId();
28
-
29
22
  logger.info(`RequestId: ${global.requestId}`);
30
23
  const { flags } = await this.parse(DiscoverCommand);
31
24
  const srs = new SourceRegistryStorage(config.get('api-mesh.sourceRegistry.path'));
@@ -58,7 +51,7 @@ class DiscoverCommand extends Command {
58
51
  } catch (error) {
59
52
  logger.error(error);
60
53
  this.error(`
61
- Something went wrong with "discover" command. Please try again later.
54
+ Something went wrong with "discover" command. Please try again later.
62
55
  ${error}
63
56
  `);
64
57
  }
@@ -12,12 +12,7 @@ governing permissions and limitations under the License.
12
12
 
13
13
  const { Command, Flags } = require('@oclif/core');
14
14
  const SourceRegistryStorage = require('source-registry-storage-adapter');
15
- const {
16
- promptMultiselect,
17
- promptSelect,
18
- promptConfirm,
19
- initRequestId,
20
- } = require('../../../helpers');
15
+ const { promptMultiselect, promptSelect, promptConfirm } = require('../../../helpers');
21
16
  const ncp = require('node-clipboardy');
22
17
  const chalk = require('chalk');
23
18
  const config = require('@adobe/aio-lib-core-config');
@@ -33,8 +28,6 @@ class GetCommand extends Command {
33
28
 
34
29
  async run() {
35
30
  try {
36
- await initRequestId();
37
-
38
31
  logger.info(`RequestId: ${global.requestId}`);
39
32
  let list;
40
33
  try {
@@ -12,7 +12,7 @@ governing permissions and limitations under the License.
12
12
 
13
13
  const { Command, Flags } = require('@oclif/core');
14
14
  const SourceRegistryStorage = require('source-registry-storage-adapter');
15
- const { promptConfirm, promptInput, initRequestId, initSdk } = require('../../../helpers');
15
+ const { promptConfirm, promptInput, initSdk } = require('../../../helpers');
16
16
  const { ignoreCacheFlag } = require('../../../utils');
17
17
  const config = require('@adobe/aio-lib-core-config');
18
18
  const logger = require('../../../classes/logger');
@@ -33,7 +33,6 @@ class InstallCommand extends Command {
33
33
 
34
34
  async run() {
35
35
  const { flags, args } = await this.parse(InstallCommand);
36
- await initRequestId();
37
36
  logger.info(`RequestId: ${global.requestId}`);
38
37
  const ignoreCache = await flags.ignoreCache;
39
38
  const {
@@ -1,7 +1,7 @@
1
1
  const { Command } = require('@oclif/core');
2
2
 
3
3
  const logger = require('../../classes/logger');
4
- const { initRequestId, initSdk } = require('../../helpers');
4
+ const { initSdk } = require('../../helpers');
5
5
  const { getMeshId, getMesh, getMeshDeployments } = require('../../lib/smsClient');
6
6
  const { ignoreCacheFlag } = require('../../utils');
7
7
 
@@ -13,7 +13,6 @@ class StatusCommand extends Command {
13
13
  };
14
14
 
15
15
  async run() {
16
- await initRequestId();
17
16
  logger.info(`RequestId: ${global.requestId}`);
18
17
 
19
18
  const { flags } = await this.parse(StatusCommand);
@@ -10,9 +10,10 @@ governing permissions and limitations under the License.
10
10
  */
11
11
 
12
12
  const { Command } = require('@oclif/command');
13
+ const chalk = require('chalk');
13
14
 
14
15
  const logger = require('../../classes/logger');
15
- const { initSdk, initRequestId, promptConfirm, importFiles } = require('../../helpers');
16
+ const { initSdk, promptConfirm, importFiles } = require('../../helpers');
16
17
  const {
17
18
  ignoreCacheFlag,
18
19
  autoConfirmActionFlag,
@@ -38,8 +39,6 @@ class UpdateCommand extends Command {
38
39
  };
39
40
 
40
41
  async run() {
41
- await initRequestId();
42
-
43
42
  logger.info(`RequestId: ${global.requestId}`);
44
43
 
45
44
  const { args, flags } = await this.parse(UpdateCommand);
@@ -106,7 +105,7 @@ class UpdateCommand extends Command {
106
105
  // if local files are present, import them in files array in meshConfig
107
106
  if (filesList.length) {
108
107
  try {
109
- data = await importFiles(data, filesList, args.file, flags.autoConfirmAction);
108
+ ({ data } = await importFiles(data, filesList, args.file, flags.autoConfirmAction));
110
109
  } catch (err) {
111
110
  this.log(err.message);
112
111
  this.error('Unable to import the files in the mesh config. Check the file and try again.');
@@ -119,8 +118,7 @@ class UpdateCommand extends Command {
119
118
  await validateSecretsFile(secretsFilePath);
120
119
  const secretsData = await interpolateSecrets(secretsFilePath, this);
121
120
  const publicKey = await getPublicEncryptionKey(imsOrgCode);
122
- const encryptedSecrets = await encryptSecrets(publicKey, secretsData);
123
- data.secrets = encryptedSecrets;
121
+ data.secrets = await encryptSecrets(publicKey, secretsData);
124
122
  } catch (err) {
125
123
  this.log(err.message);
126
124
  this.error('Unable to import secrets. Check the file and try again.');
@@ -130,6 +128,23 @@ class UpdateCommand extends Command {
130
128
  if (meshId) {
131
129
  let shouldContinue = true;
132
130
 
131
+ if (
132
+ data?.meshConfig?.responseConfig?.includeHTTPDetails &&
133
+ workspaceName.toLowerCase() === 'production'
134
+ ) {
135
+ this.warn(
136
+ `Your mesh has ${chalk.yellowBright('includeHTTPDetails')} set to ${chalk.redBright(
137
+ 'true',
138
+ )}. This is a security risk and should not be used in production.\n` +
139
+ `When ${chalk.yellowBright('includeHTTPDetails')} is set to ${chalk.redBright(
140
+ 'true',
141
+ )} it exposes HTTP request and response details in the mesh logs, which can cause sensitive information to be exposed.\n` +
142
+ `Consider setting ${chalk.yellowBright('includeHTTPDetails')} to ${chalk.greenBright(
143
+ 'false',
144
+ )} in the meshConfig.`,
145
+ );
146
+ }
147
+
133
148
  if (!autoConfirmAction) {
134
149
  shouldContinue = await promptConfirm(
135
150
  `Are you sure you want to update the mesh: ${meshId}?`,
@@ -10,21 +10,19 @@ OF ANY KIND, either express or implied. See the License for the specific languag
10
10
  governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- const IndexCommand = require('..');
13
+ const { Help, Command } = require('@oclif/core');
14
14
 
15
- test('exports', async () => {
16
- expect(typeof IndexCommand).toEqual('function');
17
- });
15
+ /**
16
+ * API Mesh command. Defers to topic for help text.
17
+ */
18
+ class ApiMeshCommand extends Command {
19
+ async run() {
20
+ const help = new Help(this.config);
21
+ await help.showHelp(['api-mesh', '--help']);
22
+ }
23
+ }
18
24
 
19
- describe('command tests', () => {
20
- let command;
25
+ ApiMeshCommand.description = 'Create, run, test, and deploy API Mesh';
26
+ ApiMeshCommand.args = [];
21
27
 
22
- beforeEach(() => {
23
- command = new IndexCommand([]);
24
- });
25
-
26
- test('run', async () => {
27
- command.argv = [];
28
- await expect(command.run()).resolves.not.toThrowError();
29
- });
30
- });
28
+ module.exports = ApiMeshCommand;
package/src/helpers.js CHANGED
@@ -437,15 +437,43 @@ async function initSdk(options) {
437
437
  /**
438
438
  * Generates a static global requestid for the lifecycle of this command request
439
439
  */
440
- async function initRequestId() {
440
+ function initRequestId() {
441
441
  global.requestId = UUID.newUuid().toString();
442
442
  }
443
443
 
444
+ /**
445
+ *
446
+ * This function initializes the metadata headers for the command execution
447
+ *
448
+ * @param {*} config
449
+ */
450
+ function initMetadata(config) {
451
+ try {
452
+ const { version, plugins, userAgent, platform, arch } = config;
453
+ const currentIntalledVersion = getCurrentInstalledPluginVersion(plugins);
454
+
455
+ const metadataHeaders = {
456
+ 'x-aio-cli-version': version,
457
+ 'x-aio-cli-user-agent': userAgent,
458
+ 'x-aio-cli-platform': platform,
459
+ 'x-aio-cli-arch': arch,
460
+ 'x-aio-cli-plugin-api-mesh-version': currentIntalledVersion,
461
+ };
462
+
463
+ global.metadataHeaders = metadataHeaders;
464
+ } catch (error) {
465
+ logger.error('Unable to initialize metadata headers');
466
+ logger.error(error.message);
467
+
468
+ global.metadataHeaders = {};
469
+ }
470
+ }
471
+
444
472
  /**
445
473
  * Function to run the CLI Y/N prompt to confirm the user's action
446
474
  *
447
475
  * @param {string} message
448
- * @returns boolean
476
+ * @returns Promise<boolean>
449
477
  */
450
478
  async function promptConfirm(message) {
451
479
  const prompt = inquirer.createPromptModule({ output: process.stderr });
@@ -505,7 +533,6 @@ async function promptSelect(message, choices) {
505
533
  * Function to run the CLI selectable list
506
534
  *
507
535
  * @param {string} message - prompt message
508
- * @param {object[]} choices - list of options
509
536
  * @returns {object[]} - selected options
510
537
  */
511
538
  async function promptInput(message) {
@@ -542,9 +569,11 @@ async function promptInputSecret(message) {
542
569
  * Import the files in the files array in meshConfig
543
570
  *
544
571
  * @param data MeshConfig
545
- * @param filesList List of files in meshConfig
572
+ * @param filesListArray List of files in meshConfig
546
573
  * @param meshConfigName MeshConfigName
547
574
  * @param autoConfirmActionFlag The user won't be prompted any questions, if this flag is set
575
+ * @param shouldMinifyJS
576
+ * @returns Promise<{{ data, localFileOverrides: string[] }}>
548
577
  */
549
578
  async function importFiles(
550
579
  data,
@@ -607,29 +636,38 @@ async function importFiles(
607
636
  );
608
637
  }
609
638
 
639
+ // Result of override resolution
640
+ const localFileOverrides = {};
610
641
  for (let i = 0; i < overrideArr.length; i++) {
642
+ const fileName = overrideArr[i].fileName;
611
643
  shouldOverride = await promptConfirm(
612
- `Do you want to override the ${path.basename(overrideArr[i].fileName)} file?`,
644
+ `Do you want to override the ${path.basename(fileName)} file?`,
613
645
  );
614
646
 
615
647
  if (shouldOverride) {
616
648
  resultData = updateFilesArray(
617
649
  resultData,
618
- overrideArr[i].fileName,
650
+ fileName,
619
651
  meshConfigName,
620
652
  overrideArr[i].index,
621
653
  shouldMinifyJS,
622
654
  );
655
+ localFileOverrides[fileName] = true;
656
+ } else {
657
+ localFileOverrides[fileName] = false;
623
658
  }
624
659
  }
625
660
 
626
- return resultData;
661
+ return {
662
+ data: resultData,
663
+ localFileOverrides,
664
+ };
627
665
  }
628
666
 
629
667
  /**loads the pupa module dynamically and then interpolates the raw data from mesh file with object data
630
- * @param {data}
631
- * @param {obj}
632
- * @returns {object} having interpolationStatus, missingKeys and interpolatedMesh
668
+ * @param data
669
+ * @param obj
670
+ * @returns {object}
633
671
  */
634
672
 
635
673
  async function interpolateMesh(data, obj) {
@@ -863,7 +901,7 @@ async function processFileConfig(config) {
863
901
  * This function sets up the tenantFiles used in a particular mesh config
864
902
  * into the tenantFiles folder
865
903
  *
866
- * @param config
904
+ * @param meshId
867
905
  */
868
906
  async function setUpTenantFiles(meshId) {
869
907
  if (fs.existsSync(path.resolve(process.cwd(), 'mesh-artifact', meshId, 'files.json'))) {
@@ -902,17 +940,36 @@ async function writeSecretsFile(secretsData, meshId) {
902
940
 
903
941
  /**
904
942
  *
905
- * This function fetches current installed version the system and the latest version from npm
943
+ * This function gets the current installed version of the plugin
906
944
  *
907
945
  * @param {*} installedPlugins
908
- * @returns { currentVersion: string, latestVersion: string }
946
+ * @returns {string || null} - current installed version of the plugin
909
947
  */
910
- async function getPluginVersionDetails(installedPlugins) {
948
+ function getCurrentInstalledPluginVersion(installedPlugins) {
911
949
  try {
912
950
  const meshPlugin = installedPlugins.find(
913
951
  ({ name }) => name === '@adobe/aio-cli-plugin-api-mesh',
914
952
  );
915
- const currentVersion = meshPlugin.version;
953
+
954
+ return meshPlugin.version;
955
+ } catch (err) {
956
+ logger.error('Unable to get current installed version');
957
+ logger.error(err.message);
958
+
959
+ return null;
960
+ }
961
+ }
962
+
963
+ /**
964
+ *
965
+ * This function fetches current installed version the system and the latest version from npm
966
+ *
967
+ * @param {*} installedPlugins
968
+ * @returns { currentVersion: string, latestVersion: string }
969
+ */
970
+ async function getPluginVersionDetails(installedPlugins) {
971
+ try {
972
+ const currentVersion = getCurrentInstalledPluginVersion(installedPlugins);
916
973
 
917
974
  let config = {
918
975
  method: 'get',
@@ -972,6 +1029,7 @@ module.exports = {
972
1029
  getDevConsoleConfig,
973
1030
  initSdk,
974
1031
  initRequestId,
1032
+ initMetadata,
975
1033
  promptSelect,
976
1034
  promptMultiselect,
977
1035
  importFiles,
@@ -0,0 +1,8 @@
1
+ const { initMetadata, initRequestId } = require('../helpers');
2
+
3
+ const hook = async function () {
4
+ initRequestId();
5
+ initMetadata(this.config);
6
+ };
7
+
8
+ module.exports = hook;
@@ -119,6 +119,7 @@ const listLogs = async (organizationCode, projectId, workspaceId, meshId, fileNa
119
119
  method: 'get',
120
120
  url: fileName ? url + `?filename=${fileName}` : url,
121
121
  headers: {
122
+ ...global?.metadataHeaders,
122
123
  'Authorization': `Bearer ${accessToken}`,
123
124
  'x-request-id': global.requestId,
124
125
  'x-api-key': SMS_API_KEY,
@@ -147,6 +148,7 @@ const getMesh = async (organizationId, projectId, workspaceId, workspaceName, me
147
148
  method: 'get',
148
149
  url: `${SMS_BASE_URL}/organizations/${organizationId}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}`,
149
150
  headers: {
151
+ ...global?.metadataHeaders,
150
152
  'Authorization': `Bearer ${accessToken}`,
151
153
  'x-request-id': global.requestId,
152
154
  'workspaceName': workspaceName,
@@ -238,6 +240,7 @@ const createMesh = async (
238
240
  method: 'post',
239
241
  url: `${SMS_BASE_URL}/organizations/${organizationId}/projects/${projectId}/workspaces/${workspaceId}/meshes`,
240
242
  headers: {
243
+ ...global?.metadataHeaders,
241
244
  'Authorization': `Bearer ${accessToken}`,
242
245
  'Content-Type': 'application/json',
243
246
  'x-request-id': global.requestId,
@@ -350,6 +353,7 @@ const updateMesh = async (
350
353
  method: 'put',
351
354
  url: `${SMS_BASE_URL}/organizations/${organizationId}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}`,
352
355
  headers: {
356
+ ...global?.metadataHeaders,
353
357
  'Authorization': `Bearer ${accessToken}`,
354
358
  'Content-Type': 'application/json',
355
359
  'x-request-id': global.requestId,
@@ -441,6 +445,7 @@ const deleteMesh = async (organizationId, projectId, workspaceId, meshId) => {
441
445
  method: 'delete',
442
446
  url: `${SMS_BASE_URL}/organizations/${organizationId}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}`,
443
447
  headers: {
448
+ ...global?.metadataHeaders,
444
449
  'Authorization': `Bearer ${accessToken}`,
445
450
  'x-request-id': global.requestId,
446
451
  'x-api-key': SMS_API_KEY,
@@ -527,6 +532,7 @@ const cachePurge = async (organizationId, projectId, workspaceId, meshId) => {
527
532
  method: 'post',
528
533
  url: `${SMS_BASE_URL}/organizations/${organizationId}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/cache/purge`,
529
534
  headers: {
535
+ ...global?.metadataHeaders,
530
536
  'Authorization': `Bearer ${accessToken}`,
531
537
  'Content-Type': 'application/json',
532
538
  'x-request-id': global.requestId,
@@ -617,6 +623,7 @@ const getMeshId = async (organizationCode, projectId, workspaceId, workspaceName
617
623
  method: 'get',
618
624
  url: `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/mesh`,
619
625
  headers: {
626
+ ...global?.metadataHeaders,
620
627
  'Authorization': `Bearer ${accessToken}`,
621
628
  'x-request-id': global.requestId,
622
629
  'workspaceName': workspaceName,
@@ -903,6 +910,7 @@ const getMeshArtifact = async (organizationId, projectId, workspaceId, workspace
903
910
  method: 'get',
904
911
  url: `${SMS_BASE_URL}/organizations/${organizationId}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/artifact`,
905
912
  headers: {
913
+ ...global?.metadataHeaders,
906
914
  'Authorization': `Bearer ${accessToken}`,
907
915
  'x-request-id': global.requestId,
908
916
  'workspaceName': workspaceName,
@@ -961,6 +969,7 @@ const getTenantFeatures = async organizationCode => {
961
969
  method: 'get',
962
970
  url: `${SMS_BASE_URL}/organizations/${organizationCode}/features`,
963
971
  headers: {
972
+ ...global?.metadataHeaders,
964
973
  'Authorization': `Bearer ${accessToken}`,
965
974
  'x-request-id': global.requestId,
966
975
  'x-api-key': SMS_API_KEY,
@@ -1016,6 +1025,7 @@ const getMeshDeployments = async (organizationCode, projectId, workspaceId, mesh
1016
1025
  method: 'get',
1017
1026
  url: `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/deployments/latest`,
1018
1027
  headers: {
1028
+ ...global?.metadataHeaders,
1019
1029
  'Authorization': `Bearer ${accessToken}`,
1020
1030
  'x-request-id': global.requestId,
1021
1031
  'x-api-key': SMS_API_KEY,
@@ -1064,7 +1074,7 @@ const getMeshDeployments = async (organizationCode, projectId, workspaceId, mesh
1064
1074
  * As a result, we provide the publicKey used for secrets encryption.
1065
1075
  * The near-term goal is to stop using Dev Console as a proxy for all routes.
1066
1076
  * @param organizationCode
1067
- * @returns string
1077
+ * @returns Promise<string>
1068
1078
  */
1069
1079
  const getPublicEncryptionKey = async organizationCode => {
1070
1080
  const { accessToken } = await getDevConsoleConfig();
@@ -1072,6 +1082,7 @@ const getPublicEncryptionKey = async organizationCode => {
1072
1082
  method: 'get',
1073
1083
  url: `${SMS_BASE_URL}/organizations/${organizationCode}/getPublicKey`,
1074
1084
  headers: {
1085
+ ...global?.metadataHeaders,
1075
1086
  'Authorization': `Bearer ${accessToken}`,
1076
1087
  'x-request-id': global.requestId,
1077
1088
  'x-api-key': SMS_API_KEY,
@@ -1117,6 +1128,7 @@ const getPresignedUrls = async (
1117
1128
  method: 'get',
1118
1129
  url: `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/logs?startDateTime=${startTime}&endDateTime=${endTime}`,
1119
1130
  headers: {
1131
+ ...global?.metadataHeaders,
1120
1132
  'Authorization': `Bearer ${accessToken}`,
1121
1133
  'x-request-id': global.requestId,
1122
1134
  'x-api-key': SMS_API_KEY,
@@ -1156,6 +1168,7 @@ const getLogsByRayId = async (organizationCode, projectId, workspaceId, meshId,
1156
1168
  method: 'get',
1157
1169
  url: `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/logs/${rayId}`,
1158
1170
  headers: {
1171
+ ...global?.metadataHeaders,
1159
1172
  'Authorization': `Bearer ${accessToken}`,
1160
1173
  'x-request-id': global.requestId,
1161
1174
  'x-api-key': SMS_API_KEY,
@@ -1384,6 +1397,106 @@ const getLogForwarding = async (organizationCode, projectId, workspaceId, meshId
1384
1397
  }
1385
1398
  };
1386
1399
 
1400
+ /**
1401
+ * Deletes the log forwarding configuration for a given mesh.
1402
+ *
1403
+ * @param {string} organizationCode - The IMS org code
1404
+ * @param {string} projectId - The project ID
1405
+ * @param {string} workspaceId - The workspace ID
1406
+ * @param {string} meshId - The mesh ID
1407
+ */
1408
+ const deleteLogForwarding = async (organizationCode, projectId, workspaceId, meshId) => {
1409
+ const { accessToken } = await getDevConsoleConfig();
1410
+ const config = {
1411
+ method: 'DELETE',
1412
+ url: `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/log/forwarding`,
1413
+ headers: {
1414
+ 'Authorization': `Bearer ${accessToken}`,
1415
+ 'x-request-id': global.requestId,
1416
+ 'x-api-key': SMS_API_KEY,
1417
+ },
1418
+ };
1419
+
1420
+ logger.info(
1421
+ 'Initiating DELETE %s',
1422
+ `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/log/forwarding`,
1423
+ );
1424
+
1425
+ try {
1426
+ const response = await axios(config);
1427
+
1428
+ logger.info('Response from DELETE %s', response.status);
1429
+
1430
+ if (response && response?.status === 204) {
1431
+ return response;
1432
+ } else {
1433
+ logger.error(
1434
+ `Unable to delete log forwarding config: ${objToString(
1435
+ response,
1436
+ ['data'],
1437
+ 'Error',
1438
+ )}. Received ${response.status}, expected 204`,
1439
+ );
1440
+ throw new Error(
1441
+ `something went wrong: ${objToString(
1442
+ response,
1443
+ ['data'],
1444
+ 'Unable to delete log forwarding',
1445
+ )}`,
1446
+ );
1447
+ }
1448
+ } catch (error) {
1449
+ logger.info('Response from DELETE %s', error.response.status);
1450
+
1451
+ if (error.response.status === 404) {
1452
+ // The request was made and the server responded with a 404 status code
1453
+ logger.error('log forwarding details not found');
1454
+
1455
+ throw new Error('log forwarding details not found');
1456
+ } else if (error.response && error.response.data) {
1457
+ // The request was made and the server responded with an unsupported status code
1458
+ logger.error(
1459
+ 'Error while deleting log forwarding details. Response: %s',
1460
+ objToString(error, ['response', 'data'], 'Unable to delete log forwarding details'),
1461
+ );
1462
+
1463
+ if (error.response.data.messages) {
1464
+ const message = objToString(
1465
+ error,
1466
+ ['response', 'data', 'messages', '0', 'message'],
1467
+ 'Unable to delete log forwarding details',
1468
+ );
1469
+
1470
+ throw new Error(message);
1471
+ } else if (error.response.data.message) {
1472
+ const message = objToString(
1473
+ error,
1474
+ ['response', 'data', 'message'],
1475
+ 'Unable to delete log forwarding details',
1476
+ );
1477
+
1478
+ throw new Error(message);
1479
+ } else {
1480
+ const message = objToString(
1481
+ error,
1482
+ ['response', 'data'],
1483
+ 'Unable to delete log forwarding details',
1484
+ );
1485
+
1486
+ throw new Error(message);
1487
+ }
1488
+ } else {
1489
+ // The request was made but no response was received
1490
+ logger.error(
1491
+ 'Error while deleting log forwarding details. No response received from the server: %s',
1492
+ objToString(error, [], 'Unable to delete log forwarding details'),
1493
+ );
1494
+
1495
+ throw new Error('Unable to delete log forwarding details: %s', error.message);
1496
+ }
1497
+ }
1498
+ };
1499
+
1387
1500
  module.exports = {
1388
1501
  getApiKeyCredential,
1389
1502
  describeMesh,
@@ -1407,4 +1520,5 @@ module.exports = {
1407
1520
  cachePurge,
1408
1521
  setLogForwarding,
1409
1522
  getLogForwarding,
1523
+ deleteLogForwarding,
1410
1524
  };