balena-cli
Version:
The official balena Command Line Interface
268 lines • 9.32 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkNotUsingOfflineMode = exports.checkLoggedInIf = void 0;
exports.authenticate = authenticate;
exports.checkLoggedIn = checkLoggedIn;
exports.askLoginType = askLoginType;
exports.selectDeviceType = selectDeviceType;
exports.confirm = confirm;
exports.selectApplication = selectApplication;
exports.selectOrganization = selectOrganization;
exports.getAndSelectOrganization = getAndSelectOrganization;
exports.getOnlineTargetDeviceUuid = getOnlineTargetDeviceUuid;
exports.selectFromList = selectFromList;
const errors_1 = require("../errors");
const lazy_1 = require("./lazy");
const validation = require("./validation");
function authenticate(options) {
const balena = (0, lazy_1.getBalenaSdk)();
return (0, lazy_1.getCliForm)()
.run([
{
message: 'Email:',
name: 'email',
type: 'input',
validate: validation.validateEmail,
},
{
message: 'Password:',
name: 'password',
type: 'password',
},
], { override: options })
.then(balena.auth.login)
.then(balena.auth.twoFactor.isPassed)
.then((isTwoFactorAuthPassed) => {
if (isTwoFactorAuthPassed) {
return;
}
return (0, lazy_1.getCliForm)()
.ask({
message: 'Two factor auth challenge:',
name: 'code',
type: 'input',
})
.then(balena.auth.twoFactor.challenge)
.catch((error) => {
return balena.auth.logout().then(() => {
if (error.name === 'BalenaRequestError' &&
error.statusCode === 401) {
throw new errors_1.ExpectedError('Invalid two factor authentication code');
}
throw error;
});
});
});
}
async function checkLoggedIn() {
const balena = (0, lazy_1.getBalenaSdk)();
if (!(await balena.auth.isLoggedIn())) {
throw new errors_1.NotLoggedInError((0, lazy_1.stripIndent) `
Login required: use the “balena login” command to log in.
`);
}
}
const checkLoggedInIf = async (doCheck) => {
if (doCheck) {
await checkLoggedIn();
}
};
exports.checkLoggedInIf = checkLoggedInIf;
const checkNotUsingOfflineMode = async () => {
if (process.env.BALENARC_OFFLINE_MODE) {
throw new errors_1.NotAvailableInOfflineModeError((0, lazy_1.stripIndent) `
This command requires an internet connection, and cannot be used in offline mode.
To leave offline mode, unset the BALENARC_OFFLINE_MODE environment variable.
`);
}
};
exports.checkNotUsingOfflineMode = checkNotUsingOfflineMode;
function askLoginType() {
return (0, lazy_1.getCliForm)().ask({
message: 'How would you like to login?',
name: 'loginType',
type: 'list',
choices: [
{
name: 'Web authorization (recommended)',
value: 'web',
},
{
name: 'Credentials',
value: 'credentials',
},
{
name: 'Authentication token',
value: 'token',
},
{
name: "I don't have a balena account!",
value: 'register',
},
],
});
}
async function selectDeviceType() {
const sdk = (0, lazy_1.getBalenaSdk)();
let deviceTypes = await sdk.models.deviceType.getAllSupported();
if (deviceTypes.length === 0) {
deviceTypes = await sdk.models.deviceType.getAll();
}
return (0, lazy_1.getCliForm)().ask({
message: 'Device Type',
type: 'list',
choices: deviceTypes.map(({ slug: value, name }) => ({
name,
value,
})),
});
}
async function confirm(yesOption, message, yesMessage, defaultValue = false) {
if (yesOption) {
if (yesMessage) {
console.log(yesMessage);
}
return;
}
const confirmed = await (0, lazy_1.getCliForm)().ask({
message,
type: 'confirm',
default: defaultValue,
});
if (!confirmed) {
throw new errors_1.ExpectedError('Aborted');
}
}
const selectApplicationPineOptions = {
$select: ['id', 'slug', 'app_name'],
$expand: {
is_for__device_type: {
$select: 'slug',
},
},
};
async function selectApplication(filter, errorOnEmptySelection = false) {
const balena = (0, lazy_1.getBalenaSdk)();
let apps = (await balena.models.application.getAllDirectlyAccessible({
...selectApplicationPineOptions,
...(filter != null && typeof filter === 'object' && { $filter: filter }),
}));
if (!apps.length) {
throw new errors_1.ExpectedError('No fleets found');
}
if (filter != null && typeof filter === 'function') {
apps = apps.filter(filter);
}
if (errorOnEmptySelection && apps.length === 0) {
throw new errors_1.ExpectedError('No suitable fleets found for selection');
}
return (0, lazy_1.getCliForm)().ask({
message: 'Select an application',
type: 'list',
choices: apps.map((application) => ({
name: `${application.app_name} (${application.slug}) [${application.is_for__device_type[0].slug}]`,
value: application,
})),
});
}
async function selectOrganization(organizations) {
organizations !== null && organizations !== void 0 ? organizations : (organizations = await (0, lazy_1.getBalenaSdk)().models.organization.getAll({
$select: ['name', 'handle'],
}));
return (0, lazy_1.getCliForm)().ask({
message: 'Select an organization',
type: 'list',
choices: organizations.map((org) => ({
name: `${org.name} (${org.handle})`,
value: org.handle,
})),
});
}
async function getAndSelectOrganization() {
const { getOwnOrganizations } = await Promise.resolve().then(() => require('./sdk'));
const organizations = await getOwnOrganizations((0, lazy_1.getBalenaSdk)(), {
$select: ['name', 'handle'],
});
if (organizations.length === 0) {
throw new Error('This account is not a member of any organizations');
}
else if (organizations.length === 1) {
return organizations[0].handle;
}
else {
return selectOrganization(organizations);
}
}
async function getOnlineTargetDeviceUuid(sdk, fleetOrDevice) {
const logger = (await Promise.resolve().then(() => require('../utils/logger'))).getLogger();
if (validation.validateUuid(fleetOrDevice)) {
let device;
try {
logger.logDebug(`Trying to fetch device by UUID ${fleetOrDevice} (${typeof fleetOrDevice})`);
device = await sdk.models.device.get(fleetOrDevice, {
$select: ['uuid', 'is_online'],
});
if (!device.is_online) {
throw new errors_1.ExpectedError(`Device with UUID ${fleetOrDevice} is disconnected`);
}
return device.uuid;
}
catch (err) {
const { BalenaDeviceNotFound } = await Promise.resolve().then(() => require('balena-errors'));
if ((0, errors_1.instanceOf)(err, BalenaDeviceNotFound)) {
logger.logDebug(`Device with UUID ${fleetOrDevice} not found`);
}
else {
throw err;
}
}
}
const application = await (async () => {
try {
logger.logDebug(`Fetching fleet ${fleetOrDevice}`);
const { getApplication } = await Promise.resolve().then(() => require('./sdk'));
return await getApplication(sdk, fleetOrDevice, {
$select: ['id', 'slug'],
$expand: {
owns__device: {
$select: ['device_name', 'uuid'],
$filter: { is_online: true },
},
},
});
}
catch (err) {
const { BalenaApplicationNotFound } = await Promise.resolve().then(() => require('balena-errors'));
if ((0, errors_1.instanceOf)(err, BalenaApplicationNotFound)) {
throw new errors_1.ExpectedError(`Fleet or Device not found: ${fleetOrDevice}`);
}
else {
throw err;
}
}
})();
const devices = application.owns__device;
if (!devices.length) {
throw new errors_1.ExpectedError(`Fleet ${application.slug} found, but has no devices online.`);
}
return (0, lazy_1.getCliForm)().ask({
message: `Select a device on fleet ${application.slug}`,
type: 'list',
default: devices[0].uuid,
choices: devices.map((device) => ({
name: `${device.device_name || 'Untitled'} (${device.uuid.slice(0, 7)})`,
value: device.uuid,
})),
});
}
function selectFromList(message, choices) {
return (0, lazy_1.getCliForm)().ask({
message,
type: 'list',
choices: choices.map((s) => ({
name: s.name,
value: s,
})),
});
}
//# sourceMappingURL=patterns.js.map
;