Fix device UUID parsing for 'balena tunnel'

Change-type: patch
This commit is contained in:
Alexis Svinartchouk 2020-08-25 13:45:39 +02:00
parent fb879d3020
commit 99a478ee39
3 changed files with 29 additions and 6 deletions

View File

@ -28,7 +28,6 @@ import { getOnlineTargetUuid } from '../utils/patterns';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { tunnelConnectionToDevice } from '../utils/tunnel'; import { tunnelConnectionToDevice } from '../utils/tunnel';
import { createServer, Server, Socket } from 'net'; import { createServer, Server, Socket } from 'net';
import { tryAsInteger } from '../utils/validation';
import { IArg } from '@oclif/parser/lib/args'; import { IArg } from '@oclif/parser/lib/args';
interface FlagsDef { interface FlagsDef {
@ -78,7 +77,6 @@ export default class TunnelCmd extends Command {
{ {
name: 'deviceOrApplication', name: 'deviceOrApplication',
description: 'device uuid or application name/id', description: 'device uuid or application name/id',
parse: (x) => tryAsInteger(x),
required: true, required: true,
}, },
]; ];

View File

@ -359,10 +359,31 @@ export function inferOrSelectDevice(preferredUuid: string) {
}); });
} }
async function getApplicationByIdOrName(
sdk: BalenaSdk.BalenaSDK,
idOrName: string,
) {
if (validation.looksLikeInteger(idOrName)) {
try {
return await sdk.models.application.get(Number(idOrName));
} catch (error) {
const { BalenaApplicationNotFound } = await import('balena-errors');
if (!instanceOf(error, BalenaApplicationNotFound)) {
throw error;
}
}
}
return await sdk.models.application.get(idOrName);
}
export async function getOnlineTargetUuid( export async function getOnlineTargetUuid(
sdk: BalenaSdk.BalenaSDK, sdk: BalenaSdk.BalenaSDK,
applicationOrDevice: string, applicationOrDevice: string,
) { ) {
// applicationOrDevice can be:
// * an application name
// * an application ID (integer)
// * a device uuid
const Logger = await import('../utils/logger'); const Logger = await import('../utils/logger');
const logger = Logger.getLogger(); const logger = Logger.getLogger();
const appTest = validation.validateApplicationName(applicationOrDevice); const appTest = validation.validateApplicationName(applicationOrDevice);
@ -390,9 +411,9 @@ export async function getOnlineTargetUuid(
// otherwise, it may be a device OR an application... // otherwise, it may be a device OR an application...
try { try {
logger.logDebug( logger.logDebug(
`Fetching application by name ${applicationOrDevice} (${typeof applicationOrDevice})`, `Fetching application by ID or name ${applicationOrDevice} (${typeof applicationOrDevice})`,
); );
const app = await sdk.models.application.get(applicationOrDevice); const app = await getApplicationByIdOrName(sdk, applicationOrDevice);
const devices = await sdk.models.device.getAllByApplication(app.id, { const devices = await sdk.models.device.getAllByApplication(app.id, {
$filter: { is_online: true }, $filter: { is_online: true },
}); });

View File

@ -75,9 +75,13 @@ export function validateUuid(input: string): boolean {
return validateLongUuid(input) || validateShortUuid(input); return validateLongUuid(input) || validateShortUuid(input);
} }
export function parseAsInteger(input: string, paramName?: string) { export function looksLikeInteger(input: string) {
// Allow only digits, no leading 0 // Allow only digits, no leading 0
if (!/^(0|[1-9][0-9]*)$/.test(input)) { return /^(?:0|[1-9][0-9]*)$/.test(input);
}
export function parseAsInteger(input: string, paramName?: string) {
if (!looksLikeInteger(input)) {
const message = const message =
paramName == null paramName == null
? 'The parameter must be an integer.' ? 'The parameter must be an integer.'