Skip to content

Commit 18b5ee1

Browse files
authored
Merge pull request #21 from tago-io/fix/export-device/APPCLI-4
fix/export-device/APPCLI-4
2 parents a1df7a9 + 1c5548d commit 18b5ee1

3 files changed

Lines changed: 55 additions & 13 deletions

File tree

src/commands/profile/export/export.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ interface IExportOptions {
2828
entity: EntityType[];
2929
setup: string;
3030
pick?: boolean;
31+
data?: string[] | true;
3132
}
3233

3334
async function resolveTokens(userConfig: IExport, options: IExportOptions) {
@@ -128,7 +129,7 @@ async function collectParameters(options: IExportOptions) {
128129

129130
// Entities that will be copied from the application.
130131
entities: options.entity,
131-
data: [],
132+
data: options.data === true ? [] : options.data,
132133

133134
// Account that entities will be copied from.
134135
export: {

src/commands/profile/export/services/devices-export.ts

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,41 @@ import { errorHandler, infoMSG } from "../../../../lib/messages";
44
import { replaceObj } from "../../../../lib/replace-obj";
55
import { IExport, IExportHolder } from "../types";
66

7+
/**
8+
* @description Replace the device token if the token being exported has the serial_number
9+
*/
10+
async function _generateDeviceToken(account: Account, import_account: Account, target_id: string, device_id: string) {
11+
let device_tokens = await account.devices.tokenList(device_id, { fields: ["name", "permission", "expire_time", "serie_number"] });
12+
device_tokens = device_tokens.filter((token) => token.serie_number);
13+
14+
if (device_tokens.length === 0) {
15+
return;
16+
}
17+
18+
const token_list = await import_account.devices.tokenList(target_id, { fields: ["serie_number", "token"] } ).then((tokens) => {
19+
const tokens_with_serial_number = tokens.filter((t) => t.serie_number);
20+
if (tokens_with_serial_number) {
21+
return tokens_with_serial_number.map((t) => t.token);
22+
}
23+
return [];
24+
});
25+
26+
for (const token of token_list) {
27+
await import_account.devices.tokenDelete(token).catch(errorHandler);
28+
}
29+
30+
for (const token of device_tokens) {
31+
await import_account.devices
32+
.tokenCreate(target_id, {
33+
name: token.name as string,
34+
permission: token.permission || "full",
35+
expire_time: "never",
36+
serie_number: token.serie_number || undefined,
37+
})
38+
.catch(errorHandler);
39+
}
40+
}
41+
742
async function deviceExport(account: Account, import_account: Account, export_holder: IExportHolder, config: IExport) {
843
infoMSG("Exporting devices: started (Max 10000 devices)");
944

@@ -37,19 +72,20 @@ async function deviceExport(account: Account, import_account: Account, export_ho
3772
if (!target_id) {
3873
({ device_id: target_id, token: new_token } = await import_account.devices.create(new_device));
3974

40-
if (config.data && config.data.length > 0) {
41-
// TODO: Support different regions
42-
const device = new Device({ token: new_token, region: config.import.region });
43-
const old_device = new Device({ token: token as string, region: config.export.region });
44-
45-
const data = await old_device.getData({
46-
variables: config.data,
47-
qty: 9999,
48-
});
49-
if (data.length > 0) {
50-
device.sendData(data).catch(errorHandler);
75+
const export_device = new Device({ token: token as string, region: config.import.region });
76+
77+
if (config.data) {
78+
const import_device = new Device({ token: new_token, region: config.export.region });
79+
80+
for await (const items of export_device.getDataStreaming({ variables: config.data })) {
81+
await import_device.sendData(items).catch(errorHandler);
5182
}
5283
}
84+
85+
// Add Configurations Parameters
86+
const export_param_list = await export_device.getParameters("all");
87+
const param_list_map = export_param_list.map(({ id, ...param }: { id: string; [key: string]: unknown }) => param);
88+
await import_account.devices.paramSet(target_id, param_list_map).catch(errorHandler);
5389
} else {
5490
await import_account.devices.edit(target_id, {
5591
parse_function: new_device.parse_function,
@@ -60,6 +96,9 @@ async function deviceExport(account: Account, import_account: Account, export_ho
6096
new_token = (await Utils.getTokenByName(import_account, target_id)) as string;
6197
}
6298

99+
// Replace the device token if the token being exported has the serial_number
100+
await _generateDeviceToken(account, import_account, target_id, device_id);
101+
63102
export_holder.devices[device_id] = target_id;
64103
export_holder.tokens[token as string] = new_token;
65104
}

src/commands/profile/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ function profileCommands(program: Command, _defaultEnvironment: string) {
3131
.option("-e, --entity <entity>", "entities that will be exported (repeatable)", handleEntities, [])
3232
.addOption(new Option("--setup [environment]", "setup a profile to be exported").conflicts(["to", "from", "from-token", "to-token"]))
3333
.option("--pick", "prompt you to pick which entities to be exported")
34+
.option("--data [variables...]", "copy device data with specified variable names (omit names to copy all)")
3435
.action(startExport)
3536
.addHelpText(
3637
"after",
@@ -44,7 +45,8 @@ function profileCommands(program: Command, _defaultEnvironment: string) {
4445
4546
${kleur.bold("Entities Export")}:
4647
- ${highlightMSG("dashboards")}: Export the dashboard label, blueprint devices, tabs, tags and widgets of the dashboard.
47-
- ${highlightMSG("devices")}: Export the devices and copy relevant data from it, after erasing the data. Must specify the data with the --data option.
48+
${kleur.bold("Note")}: To export the dashboards while preserving the relationship between Devices/Analysis, ensure they have the export_id tag or any other tag you choose.
49+
- ${highlightMSG("devices")}: Export the devices configuration. Use --data to also copy device data: --data copies all variables, --data var1 var2 copies only specified variables.
4850
If you are using device-tokens in Environment Variables or tags, you want to include the device in the export command.
4951
- ${highlightMSG("analysis")}: Export the analysis name, code, tags, mode and timeout settings.
5052
- ${highlightMSG("access")}: Export the access rules.

0 commit comments

Comments
 (0)