alwaysai
Version:
The alwaysAI command-line interface (CLI)
103 lines (94 loc) • 2.79 kB
text/typescript
import { CliTerseError } from '@alwaysai/alwayscli';
import { PLEASE_REPORT_THIS_ERROR_MESSAGE } from '../../constants';
import Sentry = require('@sentry/node');
import { promptForInput, SshSpawner, logger, stringifyError } from '../../util';
import { getTargetHardwareUuid } from '../../core/app';
import {
CliAuthenticationClient,
addDevice,
CliRpcClient,
AaiDevice
} from '../../infrastructure';
import { targetHostnameCheckComponent } from './target-hostname-check-component';
export async function deviceAddComponent(props: {
yes: boolean;
hostname?: string;
}): Promise<AaiDevice> {
const { yes } = props;
if (yes) {
throw new CliTerseError('Adding a new device is not supported with --yes');
}
const { username } = await CliAuthenticationClient().getInfo();
await enforceDevModeLimit({ username });
const deviceMode = 'development';
const friendlyName = await promptForInput({
purpose: 'to choose a device friendly name',
questions: [
{
type: 'text',
name: 'name',
message: 'Enter a device friendly name:'
}
]
});
const hostname = await targetHostnameCheckComponent({
targetHostname: props.hostname,
prompt: true
});
const hardwareId = await getTargetHardwareUuid(
SshSpawner({ targetHostname: hostname })
);
const deviceUserName = await SshSpawner({ targetHostname: hostname }).run({
exe: 'whoami'
});
const deviceToAdd = {
owner: username,
friendly_name: friendlyName.name,
host_name: hostname,
device_user_name: deviceUserName,
description: '',
hardware_ids: hardwareId,
device_hash: '',
iotKeys: ''
};
let response;
try {
response = await addDevice(deviceToAdd, deviceMode);
} catch (error) {
logger.error(stringifyError(error));
Sentry.captureException(error);
throw new CliTerseError(
`There was an error with adding a device. ${PLEASE_REPORT_THIS_ERROR_MESSAGE}`
);
}
const device: AaiDevice = {
...deviceToAdd,
id: response.deviceId,
uuid: response.deviceUUID,
mode: deviceMode,
deleted: false,
created_at: '',
updated_at: '',
cognito_device_key: ''
};
return device;
}
async function enforceDevModeLimit(props: { username: string }) {
const client = CliRpcClient();
const teams = await client.listTeamsUserIsMember({
user_name: props.username
});
const teamLimits = await client.checkTeamLimits({
team_id: teams[0].id
});
if (teamLimits.enforce_limits) {
const { dev_devices } = teamLimits;
const available =
dev_devices.limit !== null
? Math.max(dev_devices.limit - dev_devices.used, 0)
: null;
if (!available) {
throw new CliTerseError(`No available development devices left.`);
}
}
}