@newrelic/security-agent 0.0.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 (87) hide show
  1. package/CHANGELOG.md +0 -0
  2. package/CONTRIBUTING.md +23 -0
  3. package/LICENSE +43 -0
  4. package/README.md +98 -0
  5. package/THIRD_PARTY_NOTICES.md +2909 -0
  6. package/index.js +24 -0
  7. package/lib/instrumentation-security/core/constants.js +66 -0
  8. package/lib/instrumentation-security/core/event-constants.js +49 -0
  9. package/lib/instrumentation-security/core/request-manager.js +73 -0
  10. package/lib/instrumentation-security/core/route-manager.js +30 -0
  11. package/lib/instrumentation-security/core/sec-trace.js +134 -0
  12. package/lib/instrumentation-security/core/sec-utils.js +212 -0
  13. package/lib/instrumentation-security/core/security-metadata.js +34 -0
  14. package/lib/instrumentation-security/core/stack-trace.js +156 -0
  15. package/lib/instrumentation-security/hooks/director/nr-director.js +98 -0
  16. package/lib/instrumentation-security/hooks/express/nr-express.js +106 -0
  17. package/lib/instrumentation-security/hooks/fastify/nr-fastify.js +155 -0
  18. package/lib/instrumentation-security/hooks/fs/nr-fs.js +391 -0
  19. package/lib/instrumentation-security/hooks/hapi/nr-hapi.js +131 -0
  20. package/lib/instrumentation-security/hooks/http/nr-http.js +461 -0
  21. package/lib/instrumentation-security/hooks/koa/@koa/nr-@koa-router.js +110 -0
  22. package/lib/instrumentation-security/hooks/ldap/nr-ldap.js +81 -0
  23. package/lib/instrumentation-security/hooks/mongodb/common.js +239 -0
  24. package/lib/instrumentation-security/hooks/mongodb/constants.js +91 -0
  25. package/lib/instrumentation-security/hooks/mongodb/nr-mongodb.js +49 -0
  26. package/lib/instrumentation-security/hooks/mongodb/v2-mongo.js +91 -0
  27. package/lib/instrumentation-security/hooks/mongodb/v3-mongo.js +36 -0
  28. package/lib/instrumentation-security/hooks/mongodb/v4-mongo.js +17 -0
  29. package/lib/instrumentation-security/hooks/mysql/nr-mysql.js +232 -0
  30. package/lib/instrumentation-security/hooks/native/nr-childProcess.js +131 -0
  31. package/lib/instrumentation-security/hooks/postgres/nr-postgres.js +131 -0
  32. package/lib/instrumentation-security/hooks/require/nr-require.js +93 -0
  33. package/lib/instrumentation-security/hooks/restify/nr-restify.js +104 -0
  34. package/lib/instrumentation-security/hooks/xpath/nr-xpath.js +91 -0
  35. package/lib/instrumentation-security/index.js +171 -0
  36. package/lib/nr-security-agent/index.js +170 -0
  37. package/lib/nr-security-agent/lib/core/Auth-headers.js +58 -0
  38. package/lib/nr-security-agent/lib/core/ContainerProperties.js +42 -0
  39. package/lib/nr-security-agent/lib/core/ECSProperties.js +34 -0
  40. package/lib/nr-security-agent/lib/core/FuzzFailEvent.js +27 -0
  41. package/lib/nr-security-agent/lib/core/LinkingMetadata.js +21 -0
  42. package/lib/nr-security-agent/lib/core/LogMessage.js +47 -0
  43. package/lib/nr-security-agent/lib/core/PodProperties.js +36 -0
  44. package/lib/nr-security-agent/lib/core/Policy.js +105 -0
  45. package/lib/nr-security-agent/lib/core/agent-status.js +56 -0
  46. package/lib/nr-security-agent/lib/core/agent.js +146 -0
  47. package/lib/nr-security-agent/lib/core/applicationinfo.js +634 -0
  48. package/lib/nr-security-agent/lib/core/commonUtils.js +411 -0
  49. package/lib/nr-security-agent/lib/core/connections/aws-lambda-client.js +55 -0
  50. package/lib/nr-security-agent/lib/core/connections/restclient.js +20 -0
  51. package/lib/nr-security-agent/lib/core/connections/websocket/index.js +25 -0
  52. package/lib/nr-security-agent/lib/core/connections/websocket/response/collecotor-policy-error-handler.js +18 -0
  53. package/lib/nr-security-agent/lib/core/connections/websocket/response/collector-policy-handler.js +20 -0
  54. package/lib/nr-security-agent/lib/core/connections/websocket/response/fuzz-request-handler.js +171 -0
  55. package/lib/nr-security-agent/lib/core/connections/websocket/response/index.js +47 -0
  56. package/lib/nr-security-agent/lib/core/connections/websocket/response/no-op-handler.js +12 -0
  57. package/lib/nr-security-agent/lib/core/connections/websocket/response/startup-handshake-handler.js +27 -0
  58. package/lib/nr-security-agent/lib/core/connections/websocket/response/unsupported-agent-handler.js +18 -0
  59. package/lib/nr-security-agent/lib/core/connections/websocket/response/ws-reconnect.js +14 -0
  60. package/lib/nr-security-agent/lib/core/connections/websocket/websocket.js +443 -0
  61. package/lib/nr-security-agent/lib/core/event.js +186 -0
  62. package/lib/nr-security-agent/lib/core/health-check.js +159 -0
  63. package/lib/nr-security-agent/lib/core/json-file-handler.js +66 -0
  64. package/lib/nr-security-agent/lib/core/jsonValidator.js +149 -0
  65. package/lib/nr-security-agent/lib/core/lambda-delegated-task-service.js +90 -0
  66. package/lib/nr-security-agent/lib/core/logging.js +176 -0
  67. package/lib/nr-security-agent/lib/core/sec-agent-constants.js +173 -0
  68. package/lib/nr-security-agent/lib/core/sec-util.js +166 -0
  69. package/lib/nr-security-agent/lib/core/sha-size-util.js +338 -0
  70. package/lib/nr-security-agent/lib/core/sha_worker.js +24 -0
  71. package/lib/nr-security-agent/lib/core/startup-config.js +29 -0
  72. package/lib/nr-security-agent/lib/core/statusUtils.js +157 -0
  73. package/lib/nr-security-agent/lib/core/timeunit.js +44 -0
  74. package/lib/nr-security-agent/lib/core/websocket-client.js +335 -0
  75. package/lib/nr-security-agent/lib/core/worker-entities.js +82 -0
  76. package/lib/nr-security-agent/lib/core/worker.js +148 -0
  77. package/lib/nr-security-agent/lib/core/xss-utils.js +297 -0
  78. package/lib/nr-security-agent/lib/models/lambda-delegated-task/constants.js +12 -0
  79. package/lib/nr-security-agent/lib/models/lambda-delegated-task/index.js +15 -0
  80. package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-sha-calculation.js +37 -0
  81. package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-task-base.js +50 -0
  82. package/lib/nr-security-agent/lib/models/lambda-delegated-task/lambda-delegated-task-type.js +17 -0
  83. package/lib/nr-security-agent/resources/cert.pem +31 -0
  84. package/lib/nr-security-agent/resources/config.js +19 -0
  85. package/lib/nr-security-agent/resources/default-policy.yaml +36 -0
  86. package/lib/nr-security-api/index.js +111 -0
  87. package/package.json +95 -0
@@ -0,0 +1,634 @@
1
+ /*
2
+ * Copyright 2023 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const { BasicInfo } = require('./event');
9
+ const { JsonHandler } = require('./json-file-handler');
10
+ const fs = require('fs');
11
+ const shaSizeUtil = require('./sha-size-util');
12
+ const _ = require('lodash');
13
+ const OS = require('os');
14
+ const { Agent } = require('./agent');
15
+ const commonUtils = require('./commonUtils');
16
+
17
+ const events = require('events');
18
+ const eventEmitter = new events.EventEmitter();
19
+
20
+ const LOG_MESSAGES = require('./sec-agent-constants').LOG_MESSAGES;
21
+ const {
22
+ IS_LAMBDA_ENV,
23
+ AWS_LAMBDA_QUALIFIED_ARN_ENV_IDENTIFIER,
24
+ AWS_LAMBDA_FUNCTION_NAME_ENV_IDENTIFIER,
25
+ AWS_LAMBDA_FUNCTION_VERSION_ENV_IDENTIFIER,
26
+ AWS_SESSION_TOKEN_ENV_IDENTIFIER,
27
+ EMPTY_APPLICATION_UUID,
28
+ SLASH
29
+ } = require('./sec-agent-constants');
30
+ const API = require('../../../nr-security-api');
31
+ const NRAgent = API.getNRAgent();
32
+
33
+ const SELF_PROC_DIR = '/proc/self';
34
+ const CGROUP_FILE_NAME = '/proc/self/cgroup';
35
+ const STAT = '/stat';
36
+ const CMD_LINE_FILE = '/cmdline';
37
+ const DIR_IDENTIFIER = '/';
38
+ const NEW_LINE_SEPERATOR = '\n';
39
+ const CGROUP_FILE = '/cgroup';
40
+ const ESCAPED_DOT = '.';
41
+ const FINALIZED_KEYWORD = 'finalized';
42
+ const APPLICATION_INFO_KEYWORD = 'applicationinfo';
43
+ const MODULE_INTERNAL = 'module';
44
+ const STATIC_ATTACHMENT_TYPE = 'STATIC';
45
+ const SERVER_INFO_NAME = 'Node.js';
46
+ const DOCKER_IDENTIFIER = 'docker/';
47
+ const DOCKER_IDENTIFIER_1_13 = '/docker-';
48
+ const KUBPODS_IDENTIFIER = 'kubepods/';
49
+ const ECS_DIR = 'ecs/';
50
+ const LXC_IDENTIFIER = 'lxc/';
51
+ const SCOPE_IDENTIFIER = '.scope';
52
+ const SPACE_CHARACTER = ' ';
53
+ const PACKAGE_JSON_FILE = 'package.json';
54
+ const EMPTY_STRING = '';
55
+ const LIBPOD = '/libpod-';
56
+ const DOCKER_CONTAINER = '/docker/containers/';
57
+ const PROC_SELF_MOUNTINFO = '/proc/self/mountinfo';
58
+
59
+ let applicationInfo;
60
+ let isFinalized = false;
61
+
62
+ const SPACE_SEPERATOR_REGEX = /\s+/g;
63
+ const logs = require('./logging');
64
+ const logger = logs.getLogger();
65
+ const initLogger = logs.getInitLogger();
66
+
67
+ function localIpAddress () {
68
+ try {
69
+ const interfaces = Object.values(OS.networkInterfaces());
70
+ for (const iface of interfaces) {
71
+ for (const alias of iface) {
72
+ if ((alias.family === "IPv4" || alias.family === 4) && alias.address !== "127.0.0.1" && !alias.internal) {
73
+ return alias.address;
74
+ }
75
+ }
76
+ }
77
+ } catch (error) {
78
+
79
+ }
80
+ return "0.0.0.0";
81
+ }
82
+
83
+ /**
84
+ * Constructs the applicationinfo object
85
+ */
86
+ function ApplicationInfo () {
87
+ BasicInfo.apply(this);
88
+
89
+ const containerId = getContainerID();
90
+ const k8sHost = isK8S();
91
+ const ECSEnv = isECSEnv();
92
+ const isLambda = IS_LAMBDA_ENV;
93
+
94
+ this.jsonName = APPLICATION_INFO_KEYWORD;
95
+ if (NRAgent && NRAgent.config) {
96
+ this.entityGuid = NRAgent.config.entity_guid;
97
+ }
98
+ this.eventType = 'sec_appinfo';
99
+ this.startTime = Date.now();
100
+ this.binaryPath = process.execPath;
101
+ this.binaryName = process.title;
102
+ this.binaryVersion = process.versions.node;
103
+ this.libraryPath = require(MODULE_INTERNAL).globalPaths;
104
+ this.applicationUUID = commonUtils.getUUID();
105
+ this.osArch = process.arch;
106
+ this.osName = process.platform;
107
+ this.pid = process.pid;
108
+ this.userDir = process.env.PWD;
109
+ this.user = process.env.USER;
110
+ this.agentAttachmentType = STATIC_ATTACHMENT_TYPE;
111
+ this.identifier = {};
112
+
113
+ this.identifier = buildIdentifier(this.identifier);
114
+ this.identifier.envInfo = {};
115
+ this.identifier.envInfo.name = getHostName();
116
+ this.identifier.envInfo.ipaddress = localIpAddress();
117
+
118
+ if (!_.isEmpty(containerId)) {
119
+ this.identifier.id = containerId;
120
+ this.identifier.kind = "CONTAINER";
121
+ const containerProps = setContainerProperties(this.identifier);
122
+ this.identifier.envInfo = containerProps;
123
+ if (k8sHost) {
124
+ this.identifier.kind = "POD";
125
+ this.identifier.envInfo = setPodProperties(this.identifier, containerProps);
126
+ }
127
+ if (ECSEnv) {
128
+ this.identifier.kind = "ECS";
129
+ this.identifier.envInfo = setECSProperties(this.identifier);
130
+ }
131
+ } else if (isLambda) {
132
+ const lambdaARN = process.env[AWS_LAMBDA_QUALIFIED_ARN_ENV_IDENTIFIER];
133
+ const lambdaVersion = process.env[AWS_LAMBDA_FUNCTION_VERSION_ENV_IDENTIFIER];
134
+ this.applicationUUID = _.isEmpty(lambdaARN) ? ApplicationInfo.Constants.EMPTY_UUID : `${lambdaARN}:${lambdaVersion}`;
135
+ this.identifier.isHost = true;
136
+ this.identifier.isLambda = isLambda;
137
+ this.identifier.lambdaFunctionARN = _.isEmpty(lambdaARN)
138
+ ? `${process.env[AWS_LAMBDA_FUNCTION_NAME_ENV_IDENTIFIER]}:${lambdaVersion}`
139
+ : `${lambdaARN}:${lambdaVersion}`;
140
+ this.identifier.lambdaAWSSessionToken = process.env[AWS_SESSION_TOKEN_ENV_IDENTIFIER];
141
+
142
+ } else {
143
+ this.identifier.kind = "HOST";
144
+ this.identifier.envInfo = setHostProperties();
145
+ }
146
+
147
+
148
+ this.serverInfo = {};
149
+ this.serverInfo.name = SERVER_INFO_NAME;
150
+ this.runCommand = getRunCommand();
151
+ this.cmdline = process.argv;
152
+ const procStartTime = getProcStartTime(this.pid);
153
+ this.procStartTime = procStartTime || null;
154
+ }
155
+ ApplicationInfo.prototype = Object.create(BasicInfo.prototype);
156
+ ApplicationInfo.prototype.constructor = ApplicationInfo;
157
+
158
+ ApplicationInfo.prototype.getLambdaFunctioninfo = function getLambdaFunctioninfo () {
159
+ return {
160
+ isLambda: this.identifier.isLambda,
161
+ lambdaFunctionARN: this.identifier.lambdaFunctionARN,
162
+ lambdaAWSSessionToken: this.identifier.lambdaAWSSessionToken
163
+ };
164
+ };
165
+
166
+ ApplicationInfo.prototype.setUUID = function setUUID (uuid) {
167
+ this.applicationUUID = uuid;
168
+ Agent.getAgent().setApplicationInfo(this);
169
+ Agent.eventEmitter.emit(Agent.EVENTS.RECONNECT_WS_EVENT);
170
+ };
171
+
172
+ ApplicationInfo.prototype.getIdentifier = function getIdentifier () {
173
+ return this.identifier;
174
+ };
175
+
176
+ ApplicationInfo.prototype.setIdentifier = function setIdentifier (identifierJSON) {
177
+ this.identifier = identifierJSON;
178
+ };
179
+
180
+ ApplicationInfo.prototype.updateSHAAndSize = async function updateSHAAndSize (GlobalPromise) {
181
+ const applicationInfo = this;
182
+ const deployedApplications = applicationInfo && applicationInfo.serverInfo && applicationInfo.serverInfo.deployedApplications;
183
+
184
+ // set Promise object for module
185
+ shaSizeUtil.setPromise(GlobalPromise);
186
+
187
+ // if there are no applications detected
188
+ if (!deployedApplications) return;
189
+
190
+ // calculate and add sha and size info
191
+ const [application] = deployedApplications;
192
+
193
+ // For lambda we would want to skip the
194
+ // sha calculation on application files
195
+ if (IS_LAMBDA_ENV) {
196
+ return;
197
+ }
198
+
199
+ // add sha256 of binary.
200
+ applicationInfo.sha256 = await shaSizeUtil.getSHA256ForFile(process.argv[0]);
201
+
202
+ let stat = {};
203
+ if (process.hasWorker) {
204
+ stat = await getApplicationSHAAndSizeFromWorker(applicationInfo, application.deployedPath);
205
+ } else {
206
+ stat = await shaSizeUtil.getApplicationSHAAndSize(application.deployedPath, GlobalPromise);
207
+ }
208
+ application.sha256 = stat.sha256;
209
+ application.size = stat.size;
210
+ application.contextPath = '/';
211
+ application.isEmbedded = true;
212
+ process.serverPort = process.serverPort || process.env.PORT ;
213
+ application.ports = [process.serverPort || 0];
214
+ // emit finalization of application info
215
+ if (Agent.getAgent()) {
216
+ Agent.getAgent().setApplicationInfo(applicationInfo);
217
+ initLogger.info(LOG_MESSAGES.APP_INFO_GENERATED, JSON.stringify(applicationInfo));
218
+ }
219
+ };
220
+
221
+ ApplicationInfo.Constants = {
222
+ EMPTY_UUID: EMPTY_APPLICATION_UUID
223
+ };
224
+
225
+ /**
226
+ * Adds the given property and its value to
227
+ * the applicationinfo object.
228
+ *
229
+ * @param {string} property
230
+ * @param {*} value
231
+ * @throws error if property value exists.
232
+ * @throws error if applicationinfo is finalized.
233
+ *
234
+ * @returns {boolean} success
235
+ */
236
+ function addProperty (property, value) {
237
+ if (!isFinalized && applicationInfo) {
238
+ let currentObject = applicationInfo;
239
+ const properties = property.split(ESCAPED_DOT);
240
+ for (let index = 0; index < properties.length - 1; index++) {
241
+ if (currentObject[properties[index]]) {
242
+ if (typeof currentObject[properties[index]] === 'object') {
243
+ currentObject = currentObject[properties[index]];
244
+ } else {
245
+ throw new Error('CSEC-Agent: Unable to add the given property to ApplicationInfo, property value already exists!');
246
+ }
247
+ } else {
248
+ currentObject[properties[index]] = {};
249
+ currentObject = currentObject[properties[index]];
250
+ }
251
+ }
252
+ currentObject[properties[properties.length - 1]] = value;
253
+ return true;
254
+ } else {
255
+ throw new Error('CSEC-Agent: Cannot update property when ApplicationInfo is finalized or empty!');
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Returns the current instanceof applicationinfo,
261
+ * creates one if not already created.
262
+ *
263
+ * @returns {ApplicationInfo} instance
264
+ */
265
+ function getInstance () {
266
+ if (!applicationInfo) {
267
+ applicationInfo = new ApplicationInfo();
268
+ }
269
+ return applicationInfo;
270
+ }
271
+
272
+ /**
273
+ * Marks the applicationinfo as finalized.
274
+ */
275
+ function finalize () {
276
+ if (!isFinalized) {
277
+ isFinalized = true;
278
+ eventEmitter.emit(FINALIZED_KEYWORD);
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Checks if the current application info is finalized.
284
+ *
285
+ * @returns {boolean} isFinalized
286
+ */
287
+ function finalized () {
288
+ return isFinalized;
289
+ }
290
+
291
+ /**
292
+ * Retrives the container ID in which the current process
293
+ * is running.
294
+ *
295
+ * @returns {string} ContainerID if found, false otherwise.
296
+ */
297
+ function getContainerID () {
298
+ let lines, index;
299
+
300
+ // code to get containerId from /proc/self/mountinfo file
301
+ try {
302
+ const mountinfoFile = fs.readFileSync(PROC_SELF_MOUNTINFO);
303
+ lines = mountinfoFile.toString().split(NEW_LINE_SEPERATOR);
304
+ for (const st of lines) {
305
+ index = st.indexOf(DOCKER_CONTAINER);
306
+ if (index > -1) {
307
+ const splitted = st.split(DOCKER_CONTAINER);
308
+ return splitted[splitted.length - 1].split(SLASH)[0];
309
+ }
310
+ }
311
+ } catch (error) {
312
+ }
313
+
314
+ // code to get containerId from /proc/self/cgroup file
315
+ try {
316
+ const cgroupFile = fs.readFileSync(SELF_PROC_DIR + CGROUP_FILE);
317
+ lines = cgroupFile.toString().split(NEW_LINE_SEPERATOR);
318
+ } catch (err) {
319
+ return false;
320
+ }
321
+ for (const st of lines) {
322
+ index = st.lastIndexOf(DOCKER_IDENTIFIER);
323
+ if (index > -1) {
324
+ return st.substring(index + 7);
325
+ }
326
+
327
+ index = st.lastIndexOf(ECS_DIR);
328
+ if (index > -1) {
329
+ return st.substring(st.lastIndexOf(DIR_IDENTIFIER) + 1);
330
+ }
331
+
332
+ index = st.indexOf(KUBPODS_IDENTIFIER);
333
+ if (index > -1) {
334
+ return st.substring(st.lastIndexOf(DIR_IDENTIFIER) + 1);
335
+ }
336
+ // To support docker older versions
337
+ index = st.lastIndexOf(LXC_IDENTIFIER);
338
+ if (index > -1) {
339
+ return st.substring(index + 4);
340
+ }
341
+ // docker version 1.13.1
342
+ index = st.lastIndexOf(DOCKER_IDENTIFIER_1_13);
343
+ const indexEnd = st.lastIndexOf(SCOPE_IDENTIFIER);
344
+ if (index > -1 && indexEnd > -1) {
345
+ return st.substring(index + 8, indexEnd);
346
+ }
347
+
348
+ // podman
349
+ if (st.indexOf(LIBPOD) > -1 && st.indexOf(SCOPE_IDENTIFIER) > -1) {
350
+ const containerId = st.split(LIBPOD).pop().split(SCOPE_IDENTIFIER)[0];
351
+ if (!_.isEmpty(containerId)) {
352
+ return containerId;
353
+ }
354
+ }
355
+ }
356
+
357
+ return false;
358
+ }
359
+ /**
360
+ * Extracts cmdline from proc.
361
+ *
362
+ */
363
+ function getCmdLine () {
364
+ try {
365
+ const cmdlineFile = fs.readFileSync(SELF_PROC_DIR + CMD_LINE_FILE);
366
+ if (!cmdlineFile) {
367
+ return EMPTY_STRING;
368
+ }
369
+ const lines = cmdlineFile.toString().split(NEW_LINE_SEPERATOR);
370
+ const cmdline = lines[0];
371
+ if (cmdline) {
372
+ return cmdline;
373
+ }
374
+ } catch (err) {
375
+ return EMPTY_STRING;
376
+ }
377
+ }
378
+
379
+ /**
380
+ * Extracts runCommand from process var.
381
+ *
382
+ */
383
+ function getRunCommand () {
384
+ const argvs = Array.prototype.slice.call(process.argv, 0, process.argv.length);
385
+ const execArgv = Array.prototype.slice.call(process.execArgv, 0, process.execArgv.length);
386
+ const runCommand = [];
387
+ runCommand.push(argvs.shift());
388
+ let element = null;
389
+ while ((element = execArgv.shift())) {
390
+ runCommand.push(element);
391
+ }
392
+ while ((element = argvs.shift())) {
393
+ runCommand.push(element);
394
+ }
395
+ return runCommand.join(SPACE_CHARACTER);
396
+ }
397
+
398
+ /**
399
+ * Extracts process start from proc.
400
+ *
401
+ */
402
+ function getProcStartTime () {
403
+ try {
404
+ const statFile = fs.readFileSync(SELF_PROC_DIR + STAT);
405
+ if (!statFile) {
406
+ return null;
407
+ }
408
+ const lines = statFile.toString().split(NEW_LINE_SEPERATOR);
409
+ const statData = lines[0];
410
+ if (statData) {
411
+ const statArray = statData.split(SPACE_SEPERATOR_REGEX);
412
+ if (statArray.length >= 21) {
413
+ return statArray[21];
414
+ }
415
+ }
416
+ } catch (err) {
417
+ }
418
+ }
419
+
420
+ /**
421
+ * Sets version of current build
422
+ *
423
+ * @param {String} agentDir
424
+ * @param {ApplicationInfo} applicationInfo
425
+ */
426
+ function setBuildDetails (agentDir, applicationInfo) {
427
+ const jsonFileHandler = new JsonHandler(PACKAGE_JSON_FILE, agentDir);
428
+ const pkg = jsonFileHandler.getJSON();
429
+ process.env.collectorVersion = pkg.collectorVersion;
430
+ applicationInfo.collectorVersion = pkg.collectorVersion;
431
+ applicationInfo.jsonVersion = pkg.jsonVersion;
432
+ applicationInfo.buildNumber = pkg.buildNumber;
433
+ process.env.buildNumber = pkg.buildNumber;
434
+ process.env.jsonVersion = applicationInfo.jsonVersion;
435
+ }
436
+
437
+ function isK8S () {
438
+ const k8sHost = process.env.KUBERNETES_SERVICE_HOST;
439
+ if (k8sHost) {
440
+ return k8sHost;
441
+ }
442
+ return false;
443
+ }
444
+
445
+ function getHostName () {
446
+ try {
447
+ // const hostFile = fs.readFileSync("/etc/hostname");
448
+ // return hostFile.toString().trim();
449
+ return OS.hostname();
450
+ } catch (err) {
451
+ return EMPTY_STRING;
452
+ }
453
+ }
454
+
455
+
456
+ function getPodNameSpace () {
457
+ try {
458
+ const namespaceFile = fs.readFileSync('/var/run/secrets/kubernetes.io/serviceaccount/namespace');
459
+ return namespaceFile.toString('utf-8');
460
+ } catch (err) {
461
+ return EMPTY_STRING;
462
+ }
463
+ }
464
+
465
+ function isECSEnv () {
466
+ if (process.env.AWS_EXECUTION_ENV === 'AWS_ECS_FARGATE') {
467
+ return true;
468
+ }
469
+ return false;
470
+ }
471
+
472
+ function getECSTaskId () {
473
+ let lines, index;
474
+ try {
475
+ const cgroupFile = fs.readFileSync(CGROUP_FILE_NAME);
476
+ lines = cgroupFile.toString().split(NEW_LINE_SEPERATOR);
477
+ for (const st of lines) {
478
+ index = st.lastIndexOf(ECS_DIR);
479
+ if (index > -1) {
480
+ return st.substring(index + 4, st.lastIndexOf(DIR_IDENTIFIER));
481
+ }
482
+ }
483
+ } catch (err) {
484
+ return EMPTY_STRING;
485
+ }
486
+ return EMPTY_STRING;
487
+ }
488
+
489
+ function populateECSInfo (ecsObj) {
490
+ ecsObj.ecsTaskId = getECSTaskId();
491
+ const ecsData = getECSInfo();
492
+ if (!_.isEmpty(ecsData)) {
493
+ const imageId = ecsData.ImageID;
494
+ const imageName = ecsData.Image;
495
+
496
+ ecsObj.imageId = imageId;
497
+ ecsObj.imageName = imageName;
498
+
499
+ const labels = ecsData.Labels;
500
+
501
+ if (!_.isEmpty(labels)) {
502
+ const containerName = labels['com.amazonaws.ecs.container-name'];
503
+ const ecsTaskDefinitionFamily = labels['com.amazonaws.ecs.task-definition-family'];
504
+ const ecsTaskDefinitionVersion = labels['com.amazonaws.ecs.task-definition-version'];
505
+
506
+ ecsObj.containerName = containerName;
507
+ if (ecsTaskDefinitionFamily && ecsTaskDefinitionVersion) {
508
+ ecsObj.ecsTaskDefinition = ecsTaskDefinitionFamily + ':' + ecsTaskDefinitionVersion;
509
+ }
510
+ }
511
+ }
512
+ return ecsObj;
513
+ }
514
+
515
+ function getECSInfo () {
516
+ const url = process.env.ECS_CONTAINER_METADATA_URI;
517
+ let json = {};
518
+ const request = require('sync-request');
519
+ try {
520
+ const res = request('GET', url);
521
+ const body = res.getBody();
522
+ json = JSON.parse(body);
523
+ } catch (error) {
524
+ }
525
+ return json;
526
+ }
527
+
528
+ function getApplicationSHAAndSizeFromWorker (applicationInfo, applicationPath) {
529
+ const { Worker } = require('worker_threads');
530
+ return new Promise((resolve, reject) => {
531
+ const worker = new Worker(
532
+ __dirname + '/sha_worker.js', { workerData: applicationInfo });
533
+ worker.on('message', resolve);
534
+ worker.postMessage(applicationPath);
535
+ worker.on('error', reject);
536
+ worker.on('exit', (code) => {
537
+ if (code !== 0) {
538
+ reject(new Error(
539
+ `Stopped the Worker Thread of SHA256 with the exit code: ${code}`));
540
+ }
541
+ });
542
+ });
543
+ }
544
+
545
+ function buildIdentifier (identifier) {
546
+ try {
547
+ identifier.nodeId = EMPTY_STRING;
548
+ identifier.id = EMPTY_STRING;
549
+ identifier.nodeIp = EMPTY_STRING;
550
+ identifier.nodeName = NRAgent ? NRAgent.config.process_host.display_name: EMPTY_STRING;
551
+ identifier.collectorIp = localIpAddress();
552
+ } catch (e) {
553
+ logger.error(e);
554
+ }
555
+ return identifier;
556
+ }
557
+
558
+ function setHostProperties () {
559
+ const hostProp = {};
560
+ try {
561
+ hostProp.name = getHostName();
562
+ hostProp.creationTimestamp = new Date().getTime();
563
+ hostProp.state = "Running";
564
+ hostProp.os = process.platform;
565
+ hostProp.arch = process.arch;
566
+ hostProp.version = OS.release();
567
+ hostProp.buildNumber = OS.release();
568
+ hostProp.ipAddress = localIpAddress();
569
+ } catch (e) {
570
+ logger.error(e);
571
+ }
572
+
573
+ return hostProp;
574
+ }
575
+
576
+ function setContainerProperties (identifier) {
577
+ const containerProp = require("./ContainerProperties").getInstance();
578
+ try {
579
+ containerProp.id = identifier.id;
580
+ containerProp.name = getHostName();
581
+ containerProp.ipAddress = identifier.collectorIp;
582
+ containerProp.creationTimestamp = new Date().getTime();
583
+ logger.debug("containerProp", containerProp);
584
+ } catch (e) {
585
+ logger.error(e);
586
+ }
587
+ return containerProp;
588
+ }
589
+
590
+ function setPodProperties (identifier, containerProp) {
591
+ const podProp = require("./PodProperties").getInstance();
592
+ try {
593
+ podProp.id = identifier.id;
594
+ podProp.ipAddress = identifier.collectorIp;
595
+ podProp.namespace = getPodNameSpace();
596
+ podProp.name = getHostName();
597
+ podProp.creationTimestamp = new Date().getTime();
598
+ podProp.ContainerProperties.push(containerProp);
599
+ logger.debug("podProp:", podProp);
600
+ } catch (e) {
601
+ logger.error(e);
602
+ }
603
+ return podProp;
604
+ }
605
+
606
+ function setECSProperties (identifier) {
607
+ let ecsObj = {};
608
+ const ecsProp = require('./ECSProperties').getInstance();
609
+ ecsObj = populateECSInfo(ecsObj);
610
+ try {
611
+ ecsProp.id = ecsObj.ecsTaskId;
612
+ ecsProp.ipAddress = identifier.collectorIp;
613
+ ecsProp.creationTimestamp = new Date().getTime();
614
+ ecsProp.imageId = ecsObj.imageId;
615
+ ecsProp.imageName = ecsObj.imageName;
616
+ ecsProp.containerName = ecsObj.containerName;
617
+ ecsProp.containerId = '';
618
+ ecsProp.ecsTaskDefinition = ecsObj.ecsTaskDefinition;
619
+ } catch (e) {
620
+ logger.error(e);
621
+ }
622
+ return ecsProp;
623
+ }
624
+
625
+ module.exports = {
626
+ getInstance,
627
+ addProperty,
628
+ eventEmitter,
629
+ finalize,
630
+ finalized,
631
+ setBuildDetails,
632
+ getCmdLine
633
+ }
634
+ ;