2020-06-17 13:46:25 +00:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* Copyright 2016-2020 Balena Ltd.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
import Command from '../../command';
|
|
|
|
import * as cf from '../../utils/common-flags';
|
|
|
|
import { expandForAppName } from '../../utils/helpers';
|
2020-05-04 14:57:23 +00:00
|
|
|
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
|
2021-12-19 20:50:03 +00:00
|
|
|
import { applicationIdInfo, jsonInfo } from '../../utils/messages';
|
2021-07-15 13:41:38 +00:00
|
|
|
|
2023-05-23 16:42:27 +00:00
|
|
|
import type { Device, PineOptions } from 'balena-sdk';
|
2020-06-17 13:46:25 +00:00
|
|
|
|
2023-03-13 00:29:12 +00:00
|
|
|
const devicesSelectFields = {
|
2023-03-27 13:39:09 +00:00
|
|
|
$select: [
|
|
|
|
'id',
|
|
|
|
'uuid',
|
|
|
|
'device_name',
|
|
|
|
'status',
|
|
|
|
'is_online',
|
|
|
|
'supervisor_version',
|
|
|
|
'os_version',
|
|
|
|
],
|
|
|
|
} satisfies PineOptions<Device>;
|
2023-03-13 00:29:12 +00:00
|
|
|
|
2020-06-17 13:46:25 +00:00
|
|
|
export default class DevicesCmd extends Command {
|
|
|
|
public static description = stripIndent`
|
|
|
|
List all devices.
|
|
|
|
|
2021-07-15 13:41:38 +00:00
|
|
|
List all of your devices.
|
2020-06-17 13:46:25 +00:00
|
|
|
|
2021-07-15 13:41:38 +00:00
|
|
|
Devices can be filtered by fleet with the \`--fleet\` option.
|
2020-08-07 14:08:20 +00:00
|
|
|
|
2020-12-10 12:30:17 +00:00
|
|
|
${applicationIdInfo.split('\n').join('\n\t\t')}
|
|
|
|
|
|
|
|
${jsonInfo.split('\n').join('\n\t\t')}
|
2020-06-17 13:46:25 +00:00
|
|
|
`;
|
|
|
|
public static examples = [
|
|
|
|
'$ balena devices',
|
2021-07-15 13:41:38 +00:00
|
|
|
'$ balena devices --fleet MyFleet',
|
|
|
|
'$ balena devices -f myorg/myfleet',
|
2020-06-17 13:46:25 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
public static usage = 'devices';
|
|
|
|
|
2023-09-06 14:39:31 +00:00
|
|
|
public static flags = {
|
2021-12-19 20:50:03 +00:00
|
|
|
fleet: cf.fleet,
|
2020-12-10 12:30:17 +00:00
|
|
|
json: cf.json,
|
2020-06-17 13:46:25 +00:00
|
|
|
help: cf.help,
|
|
|
|
};
|
|
|
|
|
|
|
|
public static primary = true;
|
|
|
|
|
|
|
|
public static authenticated = true;
|
|
|
|
|
|
|
|
public async run() {
|
2023-09-06 14:39:31 +00:00
|
|
|
const { flags: options } = await this.parse(DevicesCmd);
|
2020-06-17 13:46:25 +00:00
|
|
|
|
|
|
|
const balena = getBalenaSdk();
|
2023-05-23 10:21:51 +00:00
|
|
|
const devicesOptions = {
|
|
|
|
...devicesSelectFields,
|
|
|
|
...expandForAppName,
|
|
|
|
$orderby: { device_name: 'asc' },
|
|
|
|
} satisfies PineOptions<Device>;
|
2020-06-17 13:46:25 +00:00
|
|
|
|
2023-05-23 16:42:27 +00:00
|
|
|
const devices = (
|
|
|
|
await (async () => {
|
|
|
|
if (options.fleet != null) {
|
|
|
|
const { getApplication } = await import('../../utils/sdk');
|
|
|
|
const application = await getApplication(balena, options.fleet, {
|
|
|
|
$select: 'slug',
|
|
|
|
$expand: {
|
|
|
|
owns__device: devicesOptions,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
return application.owns__device;
|
|
|
|
}
|
|
|
|
|
|
|
|
return await balena.pine.get({
|
|
|
|
resource: 'device',
|
|
|
|
options: devicesOptions,
|
|
|
|
});
|
|
|
|
})()
|
|
|
|
).map((device) => ({
|
|
|
|
...device,
|
|
|
|
dashboard_url: balena.models.device.getDashboardUrl(device.uuid),
|
|
|
|
fleet: device.belongs_to__application?.[0]?.slug || null,
|
|
|
|
uuid: options.json ? device.uuid : device.uuid.slice(0, 7),
|
|
|
|
device_type: device.is_of__device_type?.[0]?.slug || null,
|
|
|
|
}));
|
|
|
|
|
|
|
|
const fields: Array<keyof (typeof devices)[number]> = [
|
2020-08-07 14:08:20 +00:00
|
|
|
'id',
|
|
|
|
'uuid',
|
|
|
|
'device_name',
|
|
|
|
'device_type',
|
2021-12-20 01:13:50 +00:00
|
|
|
'fleet',
|
2020-08-07 14:08:20 +00:00
|
|
|
'status',
|
|
|
|
'is_online',
|
|
|
|
'supervisor_version',
|
|
|
|
'os_version',
|
|
|
|
'dashboard_url',
|
|
|
|
];
|
2021-07-15 13:41:38 +00:00
|
|
|
|
2020-08-07 14:08:20 +00:00
|
|
|
if (options.json) {
|
2021-07-15 13:41:38 +00:00
|
|
|
const { pickAndRename } = await import('../../utils/helpers');
|
|
|
|
const mapped = devices.map((device) => pickAndRename(device, fields));
|
|
|
|
console.log(JSON.stringify(mapped, null, 4));
|
2020-08-07 14:08:20 +00:00
|
|
|
} else {
|
2021-07-15 13:41:38 +00:00
|
|
|
const _ = await import('lodash');
|
2020-10-27 21:12:49 +00:00
|
|
|
console.log(
|
|
|
|
getVisuals().table.horizontal(
|
|
|
|
devices.map((dev) => _.mapValues(dev, (val) => val ?? 'N/a')),
|
|
|
|
fields,
|
|
|
|
),
|
|
|
|
);
|
2020-08-07 14:08:20 +00:00
|
|
|
}
|
2020-06-17 13:46:25 +00:00
|
|
|
}
|
|
|
|
}
|