@alwaysai/device-agent 1.5.0 → 2.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.
- package/lib/application-control/config.d.ts.map +1 -1
- package/lib/application-control/config.js +8 -3
- package/lib/application-control/config.js.map +1 -1
- package/lib/application-control/environment-variables.d.ts +5 -5
- package/lib/application-control/environment-variables.d.ts.map +1 -1
- package/lib/application-control/environment-variables.js +25 -38
- package/lib/application-control/environment-variables.js.map +1 -1
- package/lib/application-control/environment-variables.test.js +27 -7
- package/lib/application-control/environment-variables.test.js.map +1 -1
- package/lib/application-control/index.d.ts +4 -4
- package/lib/application-control/index.d.ts.map +1 -1
- package/lib/application-control/index.js +1 -4
- package/lib/application-control/index.js.map +1 -1
- package/lib/application-control/install.d.ts +4 -1
- package/lib/application-control/install.d.ts.map +1 -1
- package/lib/application-control/install.js +24 -8
- package/lib/application-control/install.js.map +1 -1
- package/lib/application-control/models.d.ts +0 -11
- package/lib/application-control/models.d.ts.map +1 -1
- package/lib/application-control/models.js +5 -54
- package/lib/application-control/models.js.map +1 -1
- package/lib/application-control/utils.d.ts +0 -4
- package/lib/application-control/utils.d.ts.map +1 -1
- package/lib/application-control/utils.js +12 -22
- package/lib/application-control/utils.js.map +1 -1
- package/lib/cloud-connection/base-message-handler.d.ts +27 -0
- package/lib/cloud-connection/base-message-handler.d.ts.map +1 -0
- package/lib/cloud-connection/base-message-handler.js +72 -0
- package/lib/cloud-connection/base-message-handler.js.map +1 -0
- package/lib/cloud-connection/bootstrap-provision.js +3 -2
- package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
- package/lib/cloud-connection/connection-manager.d.ts +21 -0
- package/lib/cloud-connection/connection-manager.d.ts.map +1 -0
- package/lib/cloud-connection/connection-manager.js +158 -0
- package/lib/cloud-connection/connection-manager.js.map +1 -0
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts +9 -30
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +69 -508
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/device-agent-message-handler.d.ts +22 -0
- package/lib/cloud-connection/device-agent-message-handler.d.ts.map +1 -0
- package/lib/cloud-connection/device-agent-message-handler.js +357 -0
- package/lib/cloud-connection/device-agent-message-handler.js.map +1 -0
- package/lib/cloud-connection/device-agent.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent.js +11 -9
- package/lib/cloud-connection/device-agent.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.d.ts +19 -28
- package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
- package/lib/cloud-connection/live-updates-handler.js +60 -172
- package/lib/cloud-connection/live-updates-handler.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.test.js +71 -165
- package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
- package/lib/cloud-connection/message-dispatcher.d.ts +10 -0
- package/lib/cloud-connection/message-dispatcher.d.ts.map +1 -0
- package/lib/cloud-connection/message-dispatcher.js +27 -0
- package/lib/cloud-connection/message-dispatcher.js.map +1 -0
- package/lib/cloud-connection/passthrough-handler.d.ts +4 -1
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
- package/lib/cloud-connection/passthrough-handler.js +30 -11
- package/lib/cloud-connection/passthrough-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.d.ts +11 -3
- package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
- package/lib/cloud-connection/shadow-handler.js +133 -28
- package/lib/cloud-connection/shadow-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.test.js +45 -57
- package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
- package/lib/cloud-connection/shadow.d.ts.map +1 -1
- package/lib/cloud-connection/shadow.js +2 -1
- package/lib/cloud-connection/shadow.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.d.ts +12 -3
- package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
- package/lib/cloud-connection/transaction-manager.js +29 -28
- package/lib/cloud-connection/transaction-manager.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.test.js +46 -5
- package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
- package/lib/device-control/device-control.d.ts +8 -8
- package/lib/device-control/device-control.d.ts.map +1 -1
- package/lib/device-control/device-control.js +95 -71
- package/lib/device-control/device-control.js.map +1 -1
- package/lib/docker/docker-compose.d.ts.map +1 -1
- package/lib/docker/docker-compose.js +2 -1
- package/lib/docker/docker-compose.js.map +1 -1
- package/lib/infrastructure/agent-config.d.ts +2 -1
- package/lib/infrastructure/agent-config.d.ts.map +1 -1
- package/lib/infrastructure/agent-config.js +7 -7
- package/lib/infrastructure/agent-config.js.map +1 -1
- package/lib/infrastructure/agent-config.test.js +3 -1
- package/lib/infrastructure/agent-config.test.js.map +1 -1
- package/lib/infrastructure/config-check-utility.d.ts +6 -0
- package/lib/infrastructure/config-check-utility.d.ts.map +1 -0
- package/lib/infrastructure/config-check-utility.js +67 -0
- package/lib/infrastructure/config-check-utility.js.map +1 -0
- package/lib/infrastructure/config-check-utility.test.d.ts +2 -0
- package/lib/infrastructure/config-check-utility.test.d.ts.map +1 -0
- package/lib/infrastructure/config-check-utility.test.js +109 -0
- package/lib/infrastructure/config-check-utility.test.js.map +1 -0
- package/lib/infrastructure/device-certificate.d.ts +10 -0
- package/lib/infrastructure/device-certificate.d.ts.map +1 -0
- package/lib/infrastructure/device-certificate.js +47 -0
- package/lib/infrastructure/device-certificate.js.map +1 -0
- package/lib/infrastructure/device-certificate.test.d.ts +2 -0
- package/lib/infrastructure/device-certificate.test.d.ts.map +1 -0
- package/lib/infrastructure/device-certificate.test.js +24 -0
- package/lib/infrastructure/device-certificate.test.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts +2 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.js +61 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-files.d.ts +75 -0
- package/lib/infrastructure/legacy-migration/legacy-files.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-files.js +75 -0
- package/lib/infrastructure/legacy-migration/legacy-files.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.d.ts +6 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.js +149 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts +2 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.js +226 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.js.map +1 -0
- package/lib/infrastructure/require-files-present-ready.test.d.ts +2 -0
- package/lib/infrastructure/require-files-present-ready.test.d.ts.map +1 -0
- package/lib/infrastructure/require-files-present-ready.test.js +44 -0
- package/lib/infrastructure/require-files-present-ready.test.js.map +1 -0
- package/lib/infrastructure/required-config-checks.d.ts +2 -0
- package/lib/infrastructure/required-config-checks.d.ts.map +1 -0
- package/lib/infrastructure/required-config-checks.js +30 -0
- package/lib/infrastructure/required-config-checks.js.map +1 -0
- package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
- package/lib/infrastructure/tokens-and-device-cfg.js +11 -8
- package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
- package/lib/jobs/job-handler.d.ts +23 -0
- package/lib/jobs/job-handler.d.ts.map +1 -0
- package/lib/jobs/job-handler.js +131 -0
- package/lib/jobs/job-handler.js.map +1 -0
- package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -1
- package/lib/local-connection/rabbitmq-connection.js +14 -14
- package/lib/local-connection/rabbitmq-connection.js.map +1 -1
- package/lib/secure-tunneling/secure-tunnel-message-handler.d.ts +8 -0
- package/lib/secure-tunneling/secure-tunnel-message-handler.d.ts.map +1 -0
- package/lib/secure-tunneling/secure-tunnel-message-handler.js +42 -0
- package/lib/secure-tunneling/secure-tunnel-message-handler.js.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.d.ts +9 -9
- package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.js +21 -16
- package/lib/secure-tunneling/secure-tunneling.js.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.test.js +11 -13
- package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -1
- package/lib/subcommands/app/analytics.d.ts.map +1 -1
- package/lib/subcommands/app/analytics.js +1 -2
- package/lib/subcommands/app/analytics.js.map +1 -1
- package/lib/subcommands/app/env-vars.d.ts +4 -0
- package/lib/subcommands/app/env-vars.d.ts.map +1 -1
- package/lib/subcommands/app/env-vars.js +52 -6
- package/lib/subcommands/app/env-vars.js.map +1 -1
- package/lib/subcommands/app/index.d.ts.map +1 -1
- package/lib/subcommands/app/index.js +1 -3
- package/lib/subcommands/app/index.js.map +1 -1
- package/lib/subcommands/app/models.d.ts +0 -11
- package/lib/subcommands/app/models.d.ts.map +1 -1
- package/lib/subcommands/app/models.js +2 -58
- package/lib/subcommands/app/models.js.map +1 -1
- package/lib/subcommands/app/shadow.d.ts.map +1 -1
- package/lib/subcommands/app/shadow.js +6 -5
- package/lib/subcommands/app/shadow.js.map +1 -1
- package/lib/subcommands/app/version.d.ts +2 -0
- package/lib/subcommands/app/version.d.ts.map +1 -1
- package/lib/subcommands/app/version.js +16 -6
- package/lib/subcommands/app/version.js.map +1 -1
- package/lib/subcommands/config.d.ts +2 -0
- package/lib/subcommands/config.d.ts.map +1 -0
- package/lib/subcommands/config.js +39 -0
- package/lib/subcommands/config.js.map +1 -0
- package/lib/subcommands/device/clean.d.ts +1 -1
- package/lib/subcommands/device/clean.d.ts.map +1 -1
- package/lib/subcommands/device/clean.js +23 -13
- package/lib/subcommands/device/clean.js.map +1 -1
- package/lib/subcommands/device/index.d.ts.map +1 -1
- package/lib/subcommands/device/index.js +3 -1
- package/lib/subcommands/device/index.js.map +1 -1
- package/lib/subcommands/device/init.js +8 -8
- package/lib/subcommands/device/init.js.map +1 -1
- package/lib/subcommands/device/migrate.d.ts +2 -0
- package/lib/subcommands/device/migrate.d.ts.map +1 -0
- package/lib/subcommands/device/migrate.js +24 -0
- package/lib/subcommands/device/migrate.js.map +1 -0
- package/lib/subcommands/device/refresh.d.ts.map +1 -1
- package/lib/subcommands/device/refresh.js +1 -0
- package/lib/subcommands/device/refresh.js.map +1 -1
- package/lib/subcommands/index.d.ts +1 -1
- package/lib/subcommands/index.d.ts.map +1 -1
- package/lib/subcommands/index.js +3 -1
- package/lib/subcommands/index.js.map +1 -1
- package/lib/subcommands/rabbitmq-connection.d.ts +1 -1
- package/lib/subcommands/rabbitmq-connection.d.ts.map +1 -1
- package/lib/util/aai-error.d.ts +12 -0
- package/lib/util/aai-error.d.ts.map +1 -0
- package/lib/util/aai-error.js +11 -0
- package/lib/util/aai-error.js.map +1 -0
- package/lib/util/aws-regions.d.ts +2 -0
- package/lib/util/aws-regions.d.ts.map +1 -0
- package/lib/util/{cloud-mode-ready.js → aws-regions.js} +2 -20
- package/lib/util/aws-regions.js.map +1 -0
- package/lib/util/check-for-updates.d.ts.map +1 -1
- package/lib/util/check-for-updates.js +5 -28
- package/lib/util/check-for-updates.js.map +1 -1
- package/lib/util/clean-certs.d.ts.map +1 -1
- package/lib/util/clean-certs.js +5 -4
- package/lib/util/clean-certs.js.map +1 -1
- package/lib/util/directories.d.ts +4 -18
- package/lib/util/directories.d.ts.map +1 -1
- package/lib/util/directories.js +18 -32
- package/lib/util/directories.js.map +1 -1
- package/lib/util/file.d.ts +4 -0
- package/lib/util/file.d.ts.map +1 -1
- package/lib/util/file.js +65 -4
- package/lib/util/file.js.map +1 -1
- package/lib/util/get-device-id.d.ts.map +1 -1
- package/lib/util/get-device-id.js +7 -1
- package/lib/util/get-device-id.js.map +1 -1
- package/lib/util/http-client.js +3 -3
- package/lib/util/http-client.js.map +1 -1
- package/package.json +19 -17
- package/readme.md +12 -32
- package/src/application-control/config.ts +9 -12
- package/src/application-control/environment-variables.test.ts +28 -7
- package/src/application-control/environment-variables.ts +42 -59
- package/src/application-control/index.ts +3 -16
- package/src/application-control/install.ts +39 -13
- package/src/application-control/models.ts +6 -87
- package/src/application-control/utils.ts +10 -25
- package/src/cloud-connection/base-message-handler.ts +118 -0
- package/src/cloud-connection/bootstrap-provision.ts +7 -7
- package/src/cloud-connection/connection-manager.ts +187 -0
- package/src/cloud-connection/device-agent-cloud-connection.ts +130 -723
- package/src/cloud-connection/device-agent-message-handler.ts +642 -0
- package/src/cloud-connection/device-agent.ts +16 -7
- package/src/cloud-connection/live-updates-handler.test.ts +121 -189
- package/src/cloud-connection/live-updates-handler.ts +105 -232
- package/src/cloud-connection/message-dispatcher.ts +33 -0
- package/src/cloud-connection/passthrough-handler.ts +55 -18
- package/src/cloud-connection/shadow-handler.test.ts +45 -57
- package/src/cloud-connection/shadow-handler.ts +224 -54
- package/src/cloud-connection/shadow.ts +4 -1
- package/src/cloud-connection/transaction-manager.test.ts +68 -6
- package/src/cloud-connection/transaction-manager.ts +69 -41
- package/src/device-control/device-control.ts +102 -70
- package/src/docker/docker-compose.ts +3 -2
- package/src/infrastructure/agent-config.test.ts +6 -2
- package/src/infrastructure/agent-config.ts +8 -7
- package/src/infrastructure/config-check-utility.test.ts +154 -0
- package/src/infrastructure/config-check-utility.ts +77 -0
- package/src/infrastructure/device-certificate.test.ts +40 -0
- package/src/infrastructure/device-certificate.ts +58 -0
- package/src/infrastructure/legacy-migration/legacy-file.test.ts +88 -0
- package/src/infrastructure/legacy-migration/legacy-files.ts +101 -0
- package/src/infrastructure/legacy-migration/legacy-migration.test.ts +396 -0
- package/src/infrastructure/legacy-migration/legacy-migration.ts +229 -0
- package/src/infrastructure/require-files-present-ready.test.ts +53 -0
- package/src/infrastructure/required-config-checks.ts +33 -0
- package/src/infrastructure/tokens-and-device-cfg.ts +12 -10
- package/src/jobs/job-handler.ts +146 -0
- package/src/local-connection/rabbitmq-connection.ts +22 -17
- package/src/secure-tunneling/secure-tunnel-message-handler.ts +56 -0
- package/src/secure-tunneling/secure-tunneling.test.ts +20 -22
- package/src/secure-tunneling/secure-tunneling.ts +41 -29
- package/src/subcommands/app/analytics.ts +2 -4
- package/src/subcommands/app/env-vars.ts +72 -9
- package/src/subcommands/app/index.ts +3 -11
- package/src/subcommands/app/models.ts +5 -81
- package/src/subcommands/app/shadow.ts +6 -5
- package/src/subcommands/app/version.ts +23 -6
- package/src/subcommands/config.ts +42 -0
- package/src/subcommands/device/clean.ts +31 -17
- package/src/subcommands/device/index.ts +3 -1
- package/src/subcommands/device/init.ts +11 -11
- package/src/subcommands/device/migrate.ts +20 -0
- package/src/subcommands/device/refresh.ts +1 -0
- package/src/subcommands/index.ts +3 -1
- package/src/util/aai-error.ts +20 -0
- package/src/util/{cloud-mode-ready.ts → aws-regions.ts} +0 -24
- package/src/util/check-for-updates.ts +14 -30
- package/src/util/clean-certs.ts +8 -4
- package/src/util/directories.ts +23 -67
- package/src/util/file.ts +83 -3
- package/src/util/get-device-id.ts +7 -7
- package/src/util/http-client.ts +2 -2
- package/lib/util/cloud-mode-ready.d.ts +0 -3
- package/lib/util/cloud-mode-ready.d.ts.map +0 -1
- package/lib/util/cloud-mode-ready.js.map +0 -1
- package/lib/util/download-file.d.ts +0 -6
- package/lib/util/download-file.d.ts.map +0 -1
- package/lib/util/download-file.js +0 -25
- package/lib/util/download-file.js.map +0 -1
- package/lib/util/fetch-with-timeout.d.ts +0 -4
- package/lib/util/fetch-with-timeout.d.ts.map +0 -1
- package/lib/util/fetch-with-timeout.js +0 -30
- package/lib/util/fetch-with-timeout.js.map +0 -1
- package/lib/util/parsing.d.ts +0 -2
- package/lib/util/parsing.d.ts.map +0 -1
- package/lib/util/parsing.js +0 -17
- package/lib/util/parsing.js.map +0 -1
- package/src/util/download-file.ts +0 -25
- package/src/util/fetch-with-timeout.ts +0 -35
- package/src/util/parsing.ts +0 -11
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import { device } from 'alwaysai/lib/components';
|
|
2
|
+
import { SystemId } from 'alwaysai/lib/constants';
|
|
3
|
+
import { DeviceConfigFile } from 'alwaysai/lib/core/device';
|
|
4
|
+
import {
|
|
5
|
+
DEVICE_CONFIG_FILE_NAME,
|
|
6
|
+
LocalDeviceCertificates,
|
|
7
|
+
LocalLegacyDeviceCertificates,
|
|
8
|
+
getDeviceConfigPath
|
|
9
|
+
} from 'alwaysai/lib/infrastructure';
|
|
10
|
+
import {
|
|
11
|
+
ALWAYSAI_CONFIG_FILE_NAME,
|
|
12
|
+
DEVICE_TOKEN_FILE_NAME
|
|
13
|
+
} from 'alwaysai/lib/paths';
|
|
14
|
+
import { JsSpawner, exists } from 'alwaysai/lib/util';
|
|
15
|
+
import exp from 'constants';
|
|
16
|
+
import { existsSync } from 'fs';
|
|
17
|
+
import { join } from 'path';
|
|
18
|
+
import { rimraf } from 'rimraf';
|
|
19
|
+
import * as tempy from 'tempy';
|
|
20
|
+
import { AGENT_CONFIG_FILE_NAME, AgentConfigFile } from '../agent-config';
|
|
21
|
+
import { checkAllFilesArePresent } from '../config-check-utility';
|
|
22
|
+
import {
|
|
23
|
+
getBootstrapCertificateDirectoryPath,
|
|
24
|
+
getBootstrapCertificateFileName,
|
|
25
|
+
getBootstrapIDFileName,
|
|
26
|
+
getBootstrapPrivateKeyFileName,
|
|
27
|
+
getBootstrapPrivateKeyFilePath
|
|
28
|
+
} from '../device-certificate';
|
|
29
|
+
import { requiredConfigFilesPresentAndValid } from '../required-config-checks';
|
|
30
|
+
import { LegacyFiles } from './legacy-files';
|
|
31
|
+
import {
|
|
32
|
+
migrateAgentConfigFile,
|
|
33
|
+
migrateDeviceTokens,
|
|
34
|
+
migrateFromLegacyCertsAndTokens
|
|
35
|
+
} from './legacy-migration';
|
|
36
|
+
|
|
37
|
+
describe('test migrateFromLegacyCertsAndTokens function', () => {
|
|
38
|
+
let tmpDir;
|
|
39
|
+
tmpDir = tempy.directory();
|
|
40
|
+
|
|
41
|
+
beforeAll(async () => {
|
|
42
|
+
jest.resetModules();
|
|
43
|
+
jest.clearAllMocks();
|
|
44
|
+
tmpDir = tempy.directory();
|
|
45
|
+
});
|
|
46
|
+
afterAll(async () => {
|
|
47
|
+
await rimraf(tmpDir);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
async function setupCurrentFiles(spawner, aaiConfig, deviceConfig) {
|
|
51
|
+
await spawner.mkdirp(join(tmpDir, getDeviceConfigPath()));
|
|
52
|
+
await spawner.writeFile(
|
|
53
|
+
join(tmpDir, getDeviceConfigPath(), DEVICE_CONFIG_FILE_NAME),
|
|
54
|
+
JSON.stringify(deviceConfig)
|
|
55
|
+
);
|
|
56
|
+
spawner.writeFile(
|
|
57
|
+
join(tmpDir, ALWAYSAI_CONFIG_FILE_NAME),
|
|
58
|
+
JSON.stringify(aaiConfig)
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const testCerts = new LocalDeviceCertificates(tmpDir);
|
|
62
|
+
const certFilePath = testCerts.getCertificateDirectoryName();
|
|
63
|
+
await spawner.mkdirp(join(tmpDir, getDeviceConfigPath(), certFilePath));
|
|
64
|
+
await spawner.writeFile(
|
|
65
|
+
join(
|
|
66
|
+
tmpDir,
|
|
67
|
+
getDeviceConfigPath(),
|
|
68
|
+
certFilePath,
|
|
69
|
+
testCerts.getCertificateFileName()
|
|
70
|
+
),
|
|
71
|
+
'certificate data'
|
|
72
|
+
);
|
|
73
|
+
await spawner.writeFile(
|
|
74
|
+
join(
|
|
75
|
+
tmpDir,
|
|
76
|
+
getDeviceConfigPath(),
|
|
77
|
+
certFilePath,
|
|
78
|
+
testCerts.getPrivateKeyFileName()
|
|
79
|
+
),
|
|
80
|
+
'private key data'
|
|
81
|
+
);
|
|
82
|
+
await spawner.writeFile(
|
|
83
|
+
join(
|
|
84
|
+
tmpDir,
|
|
85
|
+
getDeviceConfigPath(),
|
|
86
|
+
certFilePath,
|
|
87
|
+
testCerts.getRootCertificateFileName()
|
|
88
|
+
),
|
|
89
|
+
'root cert data'
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function setupLegacyFiles(
|
|
94
|
+
spawner,
|
|
95
|
+
aaiConfig,
|
|
96
|
+
deviceConfig,
|
|
97
|
+
agentConfig
|
|
98
|
+
) {
|
|
99
|
+
const testCerts = new LocalLegacyDeviceCertificates(tmpDir);
|
|
100
|
+
const certFilePath = testCerts.getCertificateDirectoryPath();
|
|
101
|
+
await spawner.mkdirp(certFilePath);
|
|
102
|
+
await spawner.writeFile(
|
|
103
|
+
join(tmpDir, DEVICE_TOKEN_FILE_NAME),
|
|
104
|
+
JSON.stringify(deviceConfig)
|
|
105
|
+
);
|
|
106
|
+
spawner.writeFile(
|
|
107
|
+
join(tmpDir, ALWAYSAI_CONFIG_FILE_NAME),
|
|
108
|
+
JSON.stringify(aaiConfig)
|
|
109
|
+
);
|
|
110
|
+
spawner.writeFile(
|
|
111
|
+
join(tmpDir, AGENT_CONFIG_FILE_NAME),
|
|
112
|
+
JSON.stringify(agentConfig)
|
|
113
|
+
);
|
|
114
|
+
await spawner.mkdirp(certFilePath);
|
|
115
|
+
await spawner.mkdirp(join(certFilePath, 'bootstrap-certificates'));
|
|
116
|
+
await spawner.writeFile(
|
|
117
|
+
join(testCerts.getCertificateFilePath()),
|
|
118
|
+
'certificate data'
|
|
119
|
+
);
|
|
120
|
+
await spawner.writeFile(
|
|
121
|
+
join(testCerts.getPrivateKeyFilePath()),
|
|
122
|
+
'private key data'
|
|
123
|
+
);
|
|
124
|
+
await spawner.writeFile(
|
|
125
|
+
join(testCerts.getRootCertificateFilePath()),
|
|
126
|
+
'root cert data'
|
|
127
|
+
);
|
|
128
|
+
await spawner.writeFile(
|
|
129
|
+
join(testCerts.getCertificateIdFilePath()),
|
|
130
|
+
'certificate ID data'
|
|
131
|
+
);
|
|
132
|
+
await spawner.writeFile(
|
|
133
|
+
join(
|
|
134
|
+
certFilePath,
|
|
135
|
+
'bootstrap-certificates',
|
|
136
|
+
getBootstrapCertificateFileName()
|
|
137
|
+
),
|
|
138
|
+
'certificate data'
|
|
139
|
+
);
|
|
140
|
+
await spawner.writeFile(
|
|
141
|
+
join(
|
|
142
|
+
certFilePath,
|
|
143
|
+
'bootstrap-certificates',
|
|
144
|
+
getBootstrapPrivateKeyFileName()
|
|
145
|
+
),
|
|
146
|
+
'private key data'
|
|
147
|
+
);
|
|
148
|
+
await spawner.writeFile(
|
|
149
|
+
join(certFilePath, 'bootstrap-certificates', getBootstrapIDFileName()),
|
|
150
|
+
'root cert data'
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
test('test current files present migration does not happen', async () => {
|
|
155
|
+
const spawner = JsSpawner({ path: tmpDir });
|
|
156
|
+
const legacyCredentialsConfig = {
|
|
157
|
+
deviceId: '123-4567-8910-1234',
|
|
158
|
+
refreshToken: 'refresh',
|
|
159
|
+
accessToken: 'access',
|
|
160
|
+
idToken: 'id'
|
|
161
|
+
};
|
|
162
|
+
const aaiConfig = {
|
|
163
|
+
systemId: SystemId.production,
|
|
164
|
+
deviceUuid: '123-4567-8910-1234'
|
|
165
|
+
};
|
|
166
|
+
// set up migrated/current configuration files
|
|
167
|
+
await setupCurrentFiles(spawner, legacyCredentialsConfig, aaiConfig);
|
|
168
|
+
|
|
169
|
+
const migrated = await migrateFromLegacyCertsAndTokens(tmpDir);
|
|
170
|
+
|
|
171
|
+
// check migration not called
|
|
172
|
+
expect(migrated).toBe(false);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test('test no legacy files migration does not happen', async () => {
|
|
176
|
+
const testCerts = new LocalDeviceCertificates(tmpDir);
|
|
177
|
+
const certFilePath = testCerts.getCertificateDirectoryName();
|
|
178
|
+
|
|
179
|
+
// check pre-conditions
|
|
180
|
+
expect(await exists(join(tmpDir, certFilePath))).toBe(false);
|
|
181
|
+
expect(await exists(join(tmpDir, DEVICE_CONFIG_FILE_NAME))).toBe(false);
|
|
182
|
+
expect(await exists(join(tmpDir, DEVICE_CONFIG_FILE_NAME))).toBe(false);
|
|
183
|
+
|
|
184
|
+
const migrated = await migrateFromLegacyCertsAndTokens(tmpDir);
|
|
185
|
+
|
|
186
|
+
// check migration not called
|
|
187
|
+
expect(migrated).toBe(false);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('test legacy files present but invalid and no current files present migration does not happen', async () => {
|
|
191
|
+
const spawner = JsSpawner({ path: tmpDir });
|
|
192
|
+
const legacyCredentialsConfig = {
|
|
193
|
+
deviceId: '123-abcd-8910-1234',
|
|
194
|
+
refreshToken: 'refresh',
|
|
195
|
+
accessToken: 'access',
|
|
196
|
+
idToken: 'id'
|
|
197
|
+
};
|
|
198
|
+
const aaiConfig = {
|
|
199
|
+
systemId: SystemId.production,
|
|
200
|
+
deviceUuid: '123-4567-8910-1234'
|
|
201
|
+
};
|
|
202
|
+
const agentConfig = {
|
|
203
|
+
applications: []
|
|
204
|
+
};
|
|
205
|
+
// set up legacy files
|
|
206
|
+
await setupLegacyFiles(
|
|
207
|
+
spawner,
|
|
208
|
+
aaiConfig,
|
|
209
|
+
legacyCredentialsConfig,
|
|
210
|
+
agentConfig
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
// confirm legacy files present and valid
|
|
214
|
+
const legacyFiles = LegacyFiles(tmpDir);
|
|
215
|
+
const legacyFilePaths = legacyFiles.getLegacyFileMigrationPaths();
|
|
216
|
+
const legacyFilesPresent = await checkAllFilesArePresent(
|
|
217
|
+
Object.values(legacyFilePaths)
|
|
218
|
+
);
|
|
219
|
+
expect(legacyFilesPresent).toBe(true);
|
|
220
|
+
|
|
221
|
+
// confirm that an error is thrown when the deviceUuid !== deviceId
|
|
222
|
+
await expect(
|
|
223
|
+
migrateFromLegacyCertsAndTokens(tmpDir)
|
|
224
|
+
).rejects.toThrowError();
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('test legacy files present and no current files present migration does happen', async () => {
|
|
228
|
+
const spawner = JsSpawner({ path: tmpDir });
|
|
229
|
+
const legacyCredentialsConfig = {
|
|
230
|
+
deviceId: '123-4567-8910-1234',
|
|
231
|
+
refreshToken: 'refresh',
|
|
232
|
+
accessToken: 'access',
|
|
233
|
+
idToken: 'id'
|
|
234
|
+
};
|
|
235
|
+
const aaiConfig = {
|
|
236
|
+
systemId: SystemId.production,
|
|
237
|
+
deviceUuid: '123-4567-8910-1234'
|
|
238
|
+
};
|
|
239
|
+
const agentConfig = {
|
|
240
|
+
applications: []
|
|
241
|
+
};
|
|
242
|
+
// set up legacy files
|
|
243
|
+
await setupLegacyFiles(
|
|
244
|
+
spawner,
|
|
245
|
+
aaiConfig,
|
|
246
|
+
legacyCredentialsConfig,
|
|
247
|
+
agentConfig
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// check pre-conditions
|
|
251
|
+
// check that getBootstrapPrivateKeyFilePath() returns false so that
|
|
252
|
+
// bootstrapProvision won't be called on runDeviceAgentCloudInterface
|
|
253
|
+
const newBootstrapsDir = join(
|
|
254
|
+
getBootstrapCertificateDirectoryPath(tmpDir),
|
|
255
|
+
getBootstrapPrivateKeyFileName()
|
|
256
|
+
);
|
|
257
|
+
const newBootstrapsPresent = existsSync(newBootstrapsDir);
|
|
258
|
+
expect(newBootstrapsPresent).toBe(false);
|
|
259
|
+
// check no current files exist
|
|
260
|
+
const newFilesPresentPreMigrate = await requiredConfigFilesPresentAndValid(
|
|
261
|
+
tmpDir
|
|
262
|
+
);
|
|
263
|
+
expect(newFilesPresentPreMigrate).toBe(false);
|
|
264
|
+
// check that legacy files are present
|
|
265
|
+
const legacyFiles = LegacyFiles(tmpDir);
|
|
266
|
+
const legacyFilePaths = legacyFiles.getLegacyFileMigrationPaths();
|
|
267
|
+
const legacyFilesPresent = await checkAllFilesArePresent(
|
|
268
|
+
Object.values(legacyFilePaths)
|
|
269
|
+
);
|
|
270
|
+
expect(legacyFilesPresent).toBe(true);
|
|
271
|
+
|
|
272
|
+
const migrated = await migrateFromLegacyCertsAndTokens(tmpDir);
|
|
273
|
+
|
|
274
|
+
// check output -- current files are present and valid
|
|
275
|
+
expect(migrated).toBe(true);
|
|
276
|
+
const newFilesPresentPostMigrate = await requiredConfigFilesPresentAndValid(
|
|
277
|
+
tmpDir
|
|
278
|
+
);
|
|
279
|
+
expect(newFilesPresentPostMigrate).toBe(true);
|
|
280
|
+
// check that getBootstrapPrivateKeyFilePath() returns false so that
|
|
281
|
+
// bootstrapProvision won't be called on runDeviceAgentCloudInterface
|
|
282
|
+
const newBootstrapsDirAfterMigration = join(
|
|
283
|
+
getBootstrapCertificateDirectoryPath(tmpDir),
|
|
284
|
+
getBootstrapPrivateKeyFileName()
|
|
285
|
+
);
|
|
286
|
+
const newBootstrapsPresentAfterMigration = existsSync(
|
|
287
|
+
newBootstrapsDirAfterMigration
|
|
288
|
+
);
|
|
289
|
+
expect(newBootstrapsPresentAfterMigration).toBe(false);
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
describe('test migrateDeviceTokens function', () => {
|
|
294
|
+
let tmpDir;
|
|
295
|
+
tmpDir = tempy.directory();
|
|
296
|
+
|
|
297
|
+
beforeAll(async () => {
|
|
298
|
+
tmpDir = tempy.directory();
|
|
299
|
+
});
|
|
300
|
+
afterAll(async () => {
|
|
301
|
+
await rimraf(tmpDir);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('test migrateDeviceTokens', async () => {
|
|
305
|
+
const deviceId = '123-4567-8910-1234';
|
|
306
|
+
const parsedConfig = {
|
|
307
|
+
systemId: SystemId.production,
|
|
308
|
+
deviceUuid: deviceId
|
|
309
|
+
};
|
|
310
|
+
const deviceConfig = {
|
|
311
|
+
deviceId: deviceId,
|
|
312
|
+
refreshToken: 'refresh',
|
|
313
|
+
accessToken: 'access',
|
|
314
|
+
idToken: 'id'
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
const spawner = JsSpawner({ path: tmpDir });
|
|
318
|
+
await spawner.mkdirp(join(tmpDir, getDeviceConfigPath()));
|
|
319
|
+
await spawner.writeFile(
|
|
320
|
+
join(tmpDir, DEVICE_TOKEN_FILE_NAME),
|
|
321
|
+
JSON.stringify(deviceConfig)
|
|
322
|
+
);
|
|
323
|
+
await migrateDeviceTokens(parsedConfig, tmpDir);
|
|
324
|
+
const newDeviceConfig = DeviceConfigFile(
|
|
325
|
+
join(tmpDir, getDeviceConfigPath(), DEVICE_CONFIG_FILE_NAME)
|
|
326
|
+
);
|
|
327
|
+
const parsedNewDeviceConfig = newDeviceConfig.read();
|
|
328
|
+
expect(parsedNewDeviceConfig.deviceUuid).toEqual(deviceId);
|
|
329
|
+
expect(parsedNewDeviceConfig.idToken).toEqual(deviceConfig.idToken);
|
|
330
|
+
expect(parsedNewDeviceConfig.accessToken).toEqual(deviceConfig.accessToken);
|
|
331
|
+
expect(parsedNewDeviceConfig.refreshToken).toEqual(
|
|
332
|
+
deviceConfig.refreshToken
|
|
333
|
+
);
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
describe('test migrateAgentConfigFile function', () => {
|
|
338
|
+
let tmpDir;
|
|
339
|
+
tmpDir = tempy.directory();
|
|
340
|
+
|
|
341
|
+
beforeAll(async () => {
|
|
342
|
+
tmpDir = tempy.directory();
|
|
343
|
+
});
|
|
344
|
+
afterAll(async () => {
|
|
345
|
+
await rimraf(tmpDir);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it('test migrateAgentConfigFile', async () => {
|
|
349
|
+
const newFilePath = join(
|
|
350
|
+
tmpDir,
|
|
351
|
+
getDeviceConfigPath(),
|
|
352
|
+
AGENT_CONFIG_FILE_NAME
|
|
353
|
+
);
|
|
354
|
+
const legacyFilePath = join(tmpDir, AGENT_CONFIG_FILE_NAME);
|
|
355
|
+
const spawner = JsSpawner({ path: tmpDir });
|
|
356
|
+
const legacyAgentConfigContents = {
|
|
357
|
+
applications: [
|
|
358
|
+
{
|
|
359
|
+
projectId: 'c8a1b5bd-e112-44e4-bfa4-fb9b42a4322c',
|
|
360
|
+
version:
|
|
361
|
+
'b0139ac93d91e8bd4bcb69575a7312c646f9af086b83364a3fe0b4472af04353',
|
|
362
|
+
ready: true
|
|
363
|
+
}
|
|
364
|
+
]
|
|
365
|
+
};
|
|
366
|
+
await spawner.writeFile(
|
|
367
|
+
legacyFilePath,
|
|
368
|
+
JSON.stringify(legacyAgentConfigContents)
|
|
369
|
+
);
|
|
370
|
+
const legacyFileExists = await exists(legacyFilePath);
|
|
371
|
+
expect(legacyFileExists).toEqual(true);
|
|
372
|
+
const legacyAgentConfig = AgentConfigFile(
|
|
373
|
+
join(tmpDir, AGENT_CONFIG_FILE_NAME)
|
|
374
|
+
);
|
|
375
|
+
const legacyAgentConfigReadContents = legacyAgentConfig.read();
|
|
376
|
+
expect(legacyAgentConfigReadContents.applications).toEqual(
|
|
377
|
+
legacyAgentConfigContents.applications
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
const newFileExists = await exists(newFilePath);
|
|
381
|
+
expect(newFileExists).toEqual(false);
|
|
382
|
+
|
|
383
|
+
await migrateAgentConfigFile(tmpDir);
|
|
384
|
+
|
|
385
|
+
// confirm new file is valid
|
|
386
|
+
const newAgentConfig = AgentConfigFile(
|
|
387
|
+
join(tmpDir, getDeviceConfigPath(), AGENT_CONFIG_FILE_NAME)
|
|
388
|
+
);
|
|
389
|
+
const newAgentConfigContents = newAgentConfig.read();
|
|
390
|
+
expect(newAgentConfigContents.applications).toEqual(
|
|
391
|
+
legacyAgentConfigContents.applications
|
|
392
|
+
);
|
|
393
|
+
expect(newAgentConfig.path).toEqual(newFilePath);
|
|
394
|
+
expect(legacyFileExists).toEqual(true);
|
|
395
|
+
});
|
|
396
|
+
});
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { DeviceConfig, DeviceConfigFile } from 'alwaysai/lib/core/device';
|
|
2
|
+
import {
|
|
3
|
+
CredentialsJsonFile,
|
|
4
|
+
DEVICE_CONFIG_FILE_NAME,
|
|
5
|
+
LocalDeviceCertificates,
|
|
6
|
+
getDeviceConfigPath,
|
|
7
|
+
getSystemId
|
|
8
|
+
} from 'alwaysai/lib/infrastructure';
|
|
9
|
+
import {
|
|
10
|
+
ALWAYSAI_CONFIG_FILE_NAME,
|
|
11
|
+
DEVICE_TOKEN_FILE_NAME,
|
|
12
|
+
LOCAL_AAI_CFG_DIR
|
|
13
|
+
} from 'alwaysai/lib/paths';
|
|
14
|
+
import { JsSpawner, exists, stringifyError } from 'alwaysai/lib/util';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
import rimraf from 'rimraf';
|
|
17
|
+
import {
|
|
18
|
+
checkRabbitMQContainerRunning,
|
|
19
|
+
stopRabbitMQContainer
|
|
20
|
+
} from '../../local-connection/rabbitmq-connection';
|
|
21
|
+
import { copyDir } from '../../util/copy-dir';
|
|
22
|
+
import {
|
|
23
|
+
getDeviceAgentConfigPath,
|
|
24
|
+
getDeviceAgentDockerComposePath
|
|
25
|
+
} from '../../util/directories';
|
|
26
|
+
import { logger } from '../../util/logger';
|
|
27
|
+
import { AGENT_CONFIG_FILE_NAME, AgentConfigFile } from '../agent-config';
|
|
28
|
+
import { checkAllFilesArePresent } from '../config-check-utility';
|
|
29
|
+
import { getBootstrapCertificateDirectoryPath } from '../device-certificate';
|
|
30
|
+
import { requiredConfigFilesPresentAndValid } from '../required-config-checks';
|
|
31
|
+
import {
|
|
32
|
+
LEGACY_CREDENTIALS_FILE_DIR,
|
|
33
|
+
LegacyAaiConfig,
|
|
34
|
+
LegacyAaiConfigFile,
|
|
35
|
+
LegacyFiles
|
|
36
|
+
} from './legacy-files';
|
|
37
|
+
|
|
38
|
+
/*===================================================================
|
|
39
|
+
Migration Code
|
|
40
|
+
===================================================================*/
|
|
41
|
+
|
|
42
|
+
export async function migrateAgentConfigFile(baseDir?: string) {
|
|
43
|
+
logger.debug('Migrating agent configuration file');
|
|
44
|
+
const legacyFiles = LegacyFiles(baseDir);
|
|
45
|
+
const legacyAgentConfigFile = legacyFiles.getLegacyAgentConfigFile();
|
|
46
|
+
const newAgentConfig = AgentConfigFile(
|
|
47
|
+
join(
|
|
48
|
+
baseDir ?? LOCAL_AAI_CFG_DIR,
|
|
49
|
+
getDeviceConfigPath(),
|
|
50
|
+
AGENT_CONFIG_FILE_NAME
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
let parsedAgentConfig;
|
|
54
|
+
try {
|
|
55
|
+
parsedAgentConfig = legacyAgentConfigFile.read();
|
|
56
|
+
} catch (e) {
|
|
57
|
+
logger.error(`Error reading agent config for:\n${stringifyError(e)}`);
|
|
58
|
+
logger.error(
|
|
59
|
+
`Agent Config Errors: ${JSON.stringify(
|
|
60
|
+
legacyAgentConfigFile.getErrors(),
|
|
61
|
+
null,
|
|
62
|
+
2
|
|
63
|
+
)}`
|
|
64
|
+
);
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Could not parse ${legacyAgentConfigFile.path} while migrating your legacy device files.`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
newAgentConfig.write(parsedAgentConfig);
|
|
71
|
+
|
|
72
|
+
// since this file is owned by the Device Agent
|
|
73
|
+
// we can remove it after migrating it
|
|
74
|
+
await rimraf(legacyAgentConfigFile.path);
|
|
75
|
+
} catch (e) {
|
|
76
|
+
logger.error(`Error writing agent config for:\n${stringifyError(e)}`);
|
|
77
|
+
logger.error(
|
|
78
|
+
`Agent Config Errors: ${JSON.stringify(
|
|
79
|
+
newAgentConfig.getErrors(),
|
|
80
|
+
null,
|
|
81
|
+
2
|
|
82
|
+
)}`
|
|
83
|
+
);
|
|
84
|
+
throw new Error(
|
|
85
|
+
`Could not parse ${newAgentConfig.path} while migrating your legacy device files.`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export async function migrateCertificates(baseDir?: string) {
|
|
91
|
+
logger.debug(`baseDir ${baseDir}`);
|
|
92
|
+
const legacyFiles = LegacyFiles(baseDir);
|
|
93
|
+
const legacyCerts = legacyFiles.getLegacyCertificates();
|
|
94
|
+
|
|
95
|
+
const newDeviceCertificates = new LocalDeviceCertificates(
|
|
96
|
+
baseDir ? join(baseDir, getDeviceConfigPath()) : undefined
|
|
97
|
+
);
|
|
98
|
+
const spawner = JsSpawner(baseDir ? { path: baseDir } : {});
|
|
99
|
+
await spawner.mkdirp(
|
|
100
|
+
join(newDeviceCertificates.getCertificateDirectoryPath())
|
|
101
|
+
);
|
|
102
|
+
await copyDir({
|
|
103
|
+
srcPath: legacyCerts.getCertificateDirectoryPath(),
|
|
104
|
+
destPath: newDeviceCertificates.getCertificateDirectoryPath()
|
|
105
|
+
});
|
|
106
|
+
await rimraf(getBootstrapCertificateDirectoryPath(baseDir));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export async function migrateDeviceTokens(
|
|
110
|
+
parsedAaiCfg: LegacyAaiConfig,
|
|
111
|
+
baseDir?: string
|
|
112
|
+
) {
|
|
113
|
+
const systemId = getSystemId();
|
|
114
|
+
const deviceConfigDir = baseDir
|
|
115
|
+
? join(baseDir, getDeviceConfigPath(), DEVICE_CONFIG_FILE_NAME)
|
|
116
|
+
: baseDir;
|
|
117
|
+
const deviceConfig = DeviceConfigFile(deviceConfigDir);
|
|
118
|
+
|
|
119
|
+
const deviceUuid = parsedAaiCfg?.deviceUuid;
|
|
120
|
+
if (!deviceUuid) {
|
|
121
|
+
throw new Error(`deviceUuid not found in ${ALWAYSAI_CONFIG_FILE_NAME}.`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let legacyCredentialsFile;
|
|
125
|
+
if (baseDir) {
|
|
126
|
+
legacyCredentialsFile = CredentialsJsonFile(
|
|
127
|
+
join(baseDir, DEVICE_TOKEN_FILE_NAME)
|
|
128
|
+
);
|
|
129
|
+
} else {
|
|
130
|
+
legacyCredentialsFile = CredentialsJsonFile(LEGACY_CREDENTIALS_FILE_DIR);
|
|
131
|
+
}
|
|
132
|
+
const legacyDeviceId = legacyCredentialsFile.getItem('deviceId');
|
|
133
|
+
const legacyTokens = {
|
|
134
|
+
accessToken: legacyCredentialsFile.getItem('accessToken'),
|
|
135
|
+
refreshToken: legacyCredentialsFile.getItem('refreshToken'),
|
|
136
|
+
idToken: legacyCredentialsFile.getItem('idToken')
|
|
137
|
+
};
|
|
138
|
+
const migratedTokens: DeviceConfig = {
|
|
139
|
+
...legacyTokens,
|
|
140
|
+
systemId,
|
|
141
|
+
deviceUuid
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
if (legacyDeviceId !== migratedTokens.deviceUuid) {
|
|
145
|
+
throw new Error(
|
|
146
|
+
`deviceUuid from ${LEGACY_CREDENTIALS_FILE_DIR} (${legacyDeviceId}) and ${ALWAYSAI_CONFIG_FILE_NAME} (${migratedTokens.deviceUuid}) do not match.`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
logger.debug('Copying tokens to new device config file.');
|
|
151
|
+
deviceConfig.write(migratedTokens);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export async function migrateFromLegacyCertsAndTokens(
|
|
155
|
+
baseDir?: string
|
|
156
|
+
): Promise<boolean> {
|
|
157
|
+
const requiredConfiguration = await requiredConfigFilesPresentAndValid(
|
|
158
|
+
baseDir
|
|
159
|
+
);
|
|
160
|
+
if (requiredConfiguration) {
|
|
161
|
+
logger.debug(
|
|
162
|
+
'Device appears to be properly configured, no migration needed.'
|
|
163
|
+
);
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const legacyFiles = LegacyFiles(baseDir);
|
|
168
|
+
const legacyFilePaths = legacyFiles.getLegacyFileMigrationPaths();
|
|
169
|
+
const legacyFilesPresent = await checkAllFilesArePresent(
|
|
170
|
+
Object.values(legacyFilePaths)
|
|
171
|
+
);
|
|
172
|
+
if (legacyFilesPresent) {
|
|
173
|
+
logger.debug(
|
|
174
|
+
'Legacy certs and config files found. Migrating device certs and config files to updated folders.'
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
// get device ID from original in order to pass to new AaiCfgFile
|
|
178
|
+
const aaiConfig = LegacyAaiConfigFile(baseDir);
|
|
179
|
+
let parsedAaiCfg;
|
|
180
|
+
try {
|
|
181
|
+
parsedAaiCfg = aaiConfig.read();
|
|
182
|
+
} catch (e) {
|
|
183
|
+
logger.error(`Error reading AAI config for:\n${stringifyError(e)}`);
|
|
184
|
+
logger.error(`${JSON.stringify(aaiConfig.getErrors(), null, 2)}`);
|
|
185
|
+
throw new Error(
|
|
186
|
+
`Could not parse ${aaiConfig.path} while migrating your legacy device files.`
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// migrate deviceID to new alwaysai.device.json
|
|
191
|
+
await migrateDeviceTokens(parsedAaiCfg, baseDir);
|
|
192
|
+
|
|
193
|
+
// migrate certificates
|
|
194
|
+
logger.debug('Copying legacy certificates to new file path.');
|
|
195
|
+
await migrateCertificates(baseDir);
|
|
196
|
+
|
|
197
|
+
// migrate alwaysai.agent.json to device folder
|
|
198
|
+
logger.debug('Copying agent config file to new file path.');
|
|
199
|
+
await migrateAgentConfigFile(baseDir);
|
|
200
|
+
|
|
201
|
+
// if rabbitmq container is present, stop container and migrate files
|
|
202
|
+
try {
|
|
203
|
+
if (await checkRabbitMQContainerRunning()) {
|
|
204
|
+
await stopRabbitMQContainer();
|
|
205
|
+
}
|
|
206
|
+
} catch (e) {
|
|
207
|
+
logger.error(
|
|
208
|
+
`You may need to manually stop the container by running docker-compose down in the following directory: ${getDeviceAgentDockerComposePath()}`
|
|
209
|
+
);
|
|
210
|
+
logger.debug(
|
|
211
|
+
`Error in checking / stopping RabbitMQ container!\n${stringifyError(e)}`
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
if (await exists(getDeviceAgentConfigPath(baseDir))) {
|
|
215
|
+
await copyDir({
|
|
216
|
+
srcPath: legacyFiles.getLegacyDeviceAgentConfigDirPath(),
|
|
217
|
+
destPath: getDeviceAgentConfigPath(baseDir)
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// For now, do not remove the legacy files to support legacy edgeIQ
|
|
222
|
+
|
|
223
|
+
logger.debug(`Device certs and tokens migrated successfully from legacy.`);
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
logger.debug('No legacy cert or config files found. Skipping migration.');
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkAaiConfigPresent,
|
|
3
|
+
checkCertificatesPresent,
|
|
4
|
+
checkDeviceConfigPresent
|
|
5
|
+
} from './config-check-utility';
|
|
6
|
+
import { requiredConfigFilesPresentAndValid } from './required-config-checks';
|
|
7
|
+
|
|
8
|
+
const mockedDeviceCfgCheckFunction = jest.fn();
|
|
9
|
+
const mockedCertCheckFunction = jest.fn();
|
|
10
|
+
const mockedAaiCfgCheckFunction = jest.fn();
|
|
11
|
+
|
|
12
|
+
jest.mock('./config-check-utility');
|
|
13
|
+
|
|
14
|
+
jest
|
|
15
|
+
.mocked(checkAaiConfigPresent)
|
|
16
|
+
.mockImplementation(mockedAaiCfgCheckFunction);
|
|
17
|
+
jest
|
|
18
|
+
.mocked(checkDeviceConfigPresent)
|
|
19
|
+
.mockImplementation(mockedDeviceCfgCheckFunction);
|
|
20
|
+
jest
|
|
21
|
+
.mocked(checkCertificatesPresent)
|
|
22
|
+
.mockImplementation(mockedCertCheckFunction);
|
|
23
|
+
|
|
24
|
+
describe('test requiredConfigFilesPresentAndValid', () => {
|
|
25
|
+
function setupMocks(mockDeviceCfgCheck, mockCertCheck, mockAaiCfgCheck) {
|
|
26
|
+
mockedDeviceCfgCheckFunction.mockResolvedValue(mockDeviceCfgCheck);
|
|
27
|
+
mockedCertCheckFunction.mockResolvedValue(mockCertCheck);
|
|
28
|
+
mockedAaiCfgCheckFunction.mockResolvedValue(mockAaiCfgCheck);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
it('test return value when checkDeviceConfigPresent is false', async () => {
|
|
32
|
+
setupMocks(false, true, true);
|
|
33
|
+
const newConfigsPresent = await requiredConfigFilesPresentAndValid();
|
|
34
|
+
expect(newConfigsPresent).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('test return value when checkCertificatesPresent is false', async () => {
|
|
38
|
+
setupMocks(true, false, false);
|
|
39
|
+
const newConfigsPresent = await requiredConfigFilesPresentAndValid();
|
|
40
|
+
expect(newConfigsPresent).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('test return value when checkAaiConfigPresent is false', async () => {
|
|
44
|
+
setupMocks(true, true, false);
|
|
45
|
+
const newConfigsPresent = await requiredConfigFilesPresentAndValid();
|
|
46
|
+
expect(newConfigsPresent).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('test return value when all included functions return true', async () => {
|
|
50
|
+
setupMocks(true, true, true);
|
|
51
|
+
expect(await requiredConfigFilesPresentAndValid()).toBe(true);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { logger } from '../util/logger';
|
|
2
|
+
import {
|
|
3
|
+
checkAaiConfigPresent,
|
|
4
|
+
checkCertificatesPresent,
|
|
5
|
+
checkDeviceConfigPresent
|
|
6
|
+
} from './config-check-utility';
|
|
7
|
+
|
|
8
|
+
export async function requiredConfigFilesPresentAndValid(baseDir?) {
|
|
9
|
+
// we need device/certificates, alwaysai.config.json, and device/alwaysai.device.json
|
|
10
|
+
logger.debug('Checking for required configuration files.');
|
|
11
|
+
const newDeviceConfigPresent = await checkDeviceConfigPresent(baseDir);
|
|
12
|
+
if (!newDeviceConfigPresent) {
|
|
13
|
+
logger.debug('Required device configuration is not present and valid.');
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// check new certificates are present
|
|
18
|
+
const certificatesPresent = await checkCertificatesPresent(baseDir);
|
|
19
|
+
if (!certificatesPresent) {
|
|
20
|
+
logger.debug('Required certificates paths not found.');
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// TODO: add alwaysai.config.json check here
|
|
25
|
+
const aaiConfigPresent = await checkAaiConfigPresent(baseDir);
|
|
26
|
+
if (!aaiConfigPresent) {
|
|
27
|
+
logger.debug('Required aai configuration file is not present and valid.');
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
logger.debug('All configuration files appear to be present.');
|
|
32
|
+
return true;
|
|
33
|
+
}
|