From bab98df87b181b9c1e16853ea5e5c17727a9bd3d Mon Sep 17 00:00:00 2001 From: Nick Neisen <nwneisen@gmail.com> Date: Mon, 3 Aug 2020 17:09:40 -0600 Subject: [PATCH] env add: Add ability to add env var to multiple locations in one command Change-type: minor --- doc/cli.markdown | 23 +++--- lib/actions-oclif/env/add.ts | 133 +++++++++++++++++++++++------------ tests/commands/help.spec.ts | 2 +- 3 files changed, 104 insertions(+), 54 deletions(-) diff --git a/doc/cli.markdown b/doc/cli.markdown index ffc75769..ffd9ae10 100644 --- a/doc/cli.markdown +++ b/doc/cli.markdown @@ -961,15 +961,16 @@ do not prompt for confirmation before deleting the variable ## env add NAME [VALUE] -Add an environment or config variable to an application, device or service, -as selected by the respective command-line options. Either the --application -or the --device option must be provided, and either may be be used alongside -the --service option to define a service-specific variable. (A service is an -application container in a "microservices" application.) When the --service -option is used in conjunction with the --device option, the service variable -applies to the selected device only. Otherwise, it applies to all devices of -the selected application (i.e., the application's fleet). If the --service -option is omitted, the variable applies to all services. +Add an environment or config variable to one or more applications, devices +or services, as selected by the respective command-line options. Either the +--application or the --device option must be provided, and either may be be +used alongside the --service option to define a service-specific variable. +(A service is an application container in a "microservices" application.) +When the --service option is used in conjunction with the --device option, +the service variable applies to the selected device only. Otherwise, it +applies to all devices of the selected application (i.e., the application's +fleet). If the --service option is omitted, the variable applies to all +services. If VALUE is omitted, the CLI will attempt to use the value of the environment variable of same name in the CLI process' environment. In this case, a warning @@ -988,9 +989,13 @@ Examples: $ balena env add TERM --application MyApp $ balena env add EDITOR vim --application MyApp + $ balena env add EDITOR vim --application MyApp,MyApp2 $ balena env add EDITOR vim --application MyApp --service MyService + $ balena env add EDITOR vim --application MyApp,MyApp2 --service MyService,MyService2 $ balena env add EDITOR vim --device 7cf02a6 + $ balena env add EDITOR vim --device 7cf02a6,d6f1433 $ balena env add EDITOR vim --device 7cf02a6 --service MyService + $ balena env add EDITOR vim --device 7cf02a6,d6f1433 --service MyService,MyService2 ### Arguments diff --git a/lib/actions-oclif/env/add.ts b/lib/actions-oclif/env/add.ts index 46df60c1..76a73644 100644 --- a/lib/actions-oclif/env/add.ts +++ b/lib/actions-oclif/env/add.ts @@ -39,17 +39,18 @@ interface ArgsDef { export default class EnvAddCmd extends Command { public static description = stripIndent` - Add an environment or config variable to an application, device or service. + Add an environment or config variable to one or more applications, devices or services. - Add an environment or config variable to an application, device or service, - as selected by the respective command-line options. Either the --application - or the --device option must be provided, and either may be be used alongside - the --service option to define a service-specific variable. (A service is an - application container in a "microservices" application.) When the --service - option is used in conjunction with the --device option, the service variable - applies to the selected device only. Otherwise, it applies to all devices of - the selected application (i.e., the application's fleet). If the --service - option is omitted, the variable applies to all services. + Add an environment or config variable to one or more applications, devices + or services, as selected by the respective command-line options. Either the + --application or the --device option must be provided, and either may be be + used alongside the --service option to define a service-specific variable. + (A service is an application container in a "microservices" application.) + When the --service option is used in conjunction with the --device option, + the service variable applies to the selected device only. Otherwise, it + applies to all devices of the selected application (i.e., the application's + fleet). If the --service option is omitted, the variable applies to all + services. If VALUE is omitted, the CLI will attempt to use the value of the environment variable of same name in the CLI process' environment. In this case, a warning @@ -67,9 +68,13 @@ export default class EnvAddCmd extends Command { public static examples = [ '$ balena env add TERM --application MyApp', '$ balena env add EDITOR vim --application MyApp', + '$ balena env add EDITOR vim --application MyApp,MyApp2', '$ balena env add EDITOR vim --application MyApp --service MyService', + '$ balena env add EDITOR vim --application MyApp,MyApp2 --service MyService,MyService2', '$ balena env add EDITOR vim --device 7cf02a6', + '$ balena env add EDITOR vim --device 7cf02a6,d6f1433', '$ balena env add EDITOR vim --device 7cf02a6 --service MyService', + '$ balena env add EDITOR vim --device 7cf02a6,d6f1433 --service MyService,MyService2', ]; public static args = [ @@ -147,17 +152,31 @@ export default class EnvAddCmd extends Command { const varType = isConfigVar ? 'configVar' : 'envVar'; if (options.application) { - await balena.models.application[varType].set( - options.application, - params.name, - params.value, - ); + for (const app of options.application.split(',')) { + try { + await balena.models.application[varType].set( + app, + params.name, + params.value, + ); + } catch (err) { + console.error(`${err.message}, app: ${app}`); + process.exitCode = 1; + } + } } else if (options.device) { - await balena.models.device[varType].set( - options.device, - params.name, - params.value, - ); + for (const device of options.device.split(',')) { + try { + await balena.models.device[varType].set( + device, + params.name, + params.value, + ); + } catch (err) { + console.error(`${err.message}, device: ${device}`); + process.exitCode = 1; + } + } } } } @@ -171,31 +190,57 @@ async function setServiceVars( options: FlagsDef, ) { if (options.application) { - const serviceId = await getServiceIdForApp( - sdk, - options.application, - options.service!, - ); - await sdk.models.service.var.set(serviceId, params.name, params.value!); - } else { + for (const app of options.application.split(',')) { + for (const service of options.service!.split(',')) { + try { + const serviceId = await getServiceIdForApp(sdk, app, service); + await sdk.models.service.var.set( + serviceId, + params.name, + params.value!, + ); + } catch (err) { + console.error(`${err.message}, application: ${app}`); + process.exitCode = 1; + } + } + } + } else if (options.device) { const { getDeviceAndAppFromUUID } = await import('../../utils/cloud'); - const [device, app] = await getDeviceAndAppFromUUID( - sdk, - options.device!, - ['id'], - ['app_name'], - ); - const serviceId = await getServiceIdForApp( - sdk, - app.app_name, - options.service!, - ); - await sdk.models.device.serviceVar.set( - device.id, - serviceId, - params.name, - params.value!, - ); + for (const uuid of options.device.split(',')) { + let device; + let app; + try { + [device, app] = await getDeviceAndAppFromUUID( + sdk, + uuid, + ['id'], + ['app_name'], + ); + } catch (err) { + console.error(`${err.message}, device: ${uuid}`); + process.exitCode = 1; + continue; + } + for (const service of options.service!.split(',')) { + try { + const serviceId = await getServiceIdForApp( + sdk, + app.app_name, + service, + ); + await sdk.models.device.serviceVar.set( + device.id, + serviceId, + params.name, + params.value!, + ); + } catch (err) { + console.error(`${err.message}, service: ${service}`); + process.exitCode = 1; + } + } + } } } diff --git a/tests/commands/help.spec.ts b/tests/commands/help.spec.ts index 36ab885a..910bfcbd 100644 --- a/tests/commands/help.spec.ts +++ b/tests/commands/help.spec.ts @@ -67,7 +67,7 @@ Additional commands: device rm <uuid(s)> remove one or more devices device shutdown <uuid> shutdown a device devices supported list the supported device types (like 'raspberrypi3' or 'intel-nuc') - env add <name> [value] add an environment or config variable to an application, device or service + env add <name> [value] add an environment or config variable to one or more applications, devices or services env rename <id> <value> change the value of a config or env var for an app, device or service env rm <id> remove a config or env var from an application, device or service envs list the environment or config variables of an application, device or service