Add multicontainer (microservices) support for 'balena env rm'

Change-type: minor
Signed-off-by: Paulo Castro <paulo@balena.io>
This commit is contained in:
Paulo Castro 2019-12-11 00:43:55 +00:00
parent 90e184ea1f
commit 7c1faa6de0
4 changed files with 185 additions and 66 deletions

View File

@ -662,45 +662,70 @@ service name
## env rm ID
Remove a configuration or environment variable from an application or device,
as selected by command-line options.
Remove a configuration or environment variable from an application, device
or service, as selected by command-line options.
Note that this command asks for confirmation interactively.
You can avoid this by passing the `--yes` boolean option.
Variables are selected by their database ID (as reported by the 'balena envs'
command) and one of six database "resource types":
The --device option selects a device instead of an application.
The --config option selects a config var instead of an env var.
- application (fleet) environment variable
- application (fleet) configuration variable (--config)
- application (fleet) service variable (--service)
- device environment variable (--device)
- device configuration variable (--device --config)
- device service variable (--device --service)
Service-specific variables are not currently supported. The following
examples remove variables that apply to all services in an app or device.
The --device option selects a device-specific variable instead of an application
(fleet) variable.
The --config option selects a configuration variable. Configuration variable
names typically start with the 'BALENA_' or 'RESIN_' prefixes and are used to
configure balena platform features.
The --service option selects a service variable, which is an environment variable
that applies to a specifc service (application container) in a microservices
(multicontainer) application.
The --service and --config options cannot be used together, but they can be
used alongside the --device option to select a device-specific service or
configuration variable.
Interactive confirmation is normally asked before the variable is deleted.
The --yes option disables this behaviour.
Examples:
$ balena env rm 215
$ balena env rm 215 --yes
$ balena env rm 215 --config
$ balena env rm 215 --device
$ balena env rm 215 --device --config
$ balena env rm 123123
$ balena env rm 234234 --yes
$ balena env rm 345345 --config
$ balena env rm 456456 --service
$ balena env rm 567567 --device
$ balena env rm 678678 --device --config
$ balena env rm 789789 --device --service --yes
### Arguments
#### ID
environment variable numeric database ID
variable's numeric database ID
### Options
#### -d, --device
Selects a device environment variable instead of an application environment variable
#### -c, --config
Selects a configuration variable instead of an environment variable
select a configuration variable (may be used together with the --device option)
#### -d, --device
select a device-specific variable instead of an application (fleet) variable
#### -s, --service
select a service variable (may be used together with the --device option)
#### -y, --yes
Run in non-interactive mode
do not prompt for confirmation before deleting the variable
## env add NAME [VALUE]

View File

@ -18,12 +18,15 @@
import { Command, flags } from '@oclif/command';
import { stripIndent } from 'common-tags';
import { ExpectedError } from '../../errors';
import * as ec from '../../utils/env-common';
import { CommandHelp } from '../../utils/oclif-utils';
type IArg<T> = import('@oclif/parser').args.IArg<T>;
interface FlagsDef {
config: boolean;
device: boolean;
service: boolean;
yes: boolean;
}
@ -33,62 +36,53 @@ interface ArgsDef {
export default class EnvRmCmd extends Command {
public static description = stripIndent`
Remove an environment variable from an application or device.
Remove a config or env var from an application, device or service.
Remove a configuration or environment variable from an application or device,
as selected by command-line options.
Remove a configuration or environment variable from an application, device
or service, as selected by command-line options.
Note that this command asks for confirmation interactively.
You can avoid this by passing the \`--yes\` boolean option.
${ec.rmRenameHelp.split('\n').join('\n\t\t')}
The --device option selects a device instead of an application.
The --config option selects a config var instead of an env var.
Service-specific variables are not currently supported. The following
examples remove variables that apply to all services in an app or device.
Interactive confirmation is normally asked before the variable is deleted.
The --yes option disables this behaviour.
`;
public static examples = [
'$ balena env rm 215',
'$ balena env rm 215 --yes',
'$ balena env rm 215 --config',
'$ balena env rm 215 --device',
'$ balena env rm 215 --device --config',
'$ balena env rm 123123',
'$ balena env rm 234234 --yes',
'$ balena env rm 345345 --config',
'$ balena env rm 456456 --service',
'$ balena env rm 567567 --device',
'$ balena env rm 678678 --device --config',
'$ balena env rm 789789 --device --service --yes',
];
public static args = [
public static args: Array<IArg<any>> = [
{
name: 'id',
required: true,
description: 'environment variable numeric database ID',
description: "variable's numeric database ID",
parse: input => ec.parseDbId(input),
},
];
// hardcoded 'env add' to avoid oclif's 'env:add' topic syntax
// hardcoded 'env rm' to avoid oclif's 'env:rm' topic syntax
public static usage =
'env rm ' + new CommandHelp({ args: EnvRmCmd.args }).defaultUsage();
public static flags: flags.Input<FlagsDef> = {
device: flags.boolean({
char: 'd',
description:
'Selects a device environment variable instead of an application environment variable',
default: false,
}),
config: flags.boolean({
char: 'c',
description:
'Selects a configuration variable instead of an environment variable',
default: false,
}),
config: ec.booleanConfig,
device: ec.booleanDevice,
service: ec.booleanService,
yes: flags.boolean({
char: 'y',
description: 'Run in non-interactive mode',
description:
'do not prompt for confirmation before deleting the variable',
default: false,
}),
};
public async run() {
const { args: params, flags: options } = this.parse<FlagsDef, ArgsDef>(
const { args: params, flags: opt } = this.parse<FlagsDef, ArgsDef>(
EnvRmCmd,
);
const balena = (await import('balena-sdk')).fromSharedOptions();
@ -96,25 +90,15 @@ export default class EnvRmCmd extends Command {
await checkLoggedIn();
if (isNaN(params.id) || !Number.isInteger(Number(params.id))) {
throw new ExpectedError('The environment variable id must be an integer');
}
await confirm(
options.yes || false,
opt.yes || false,
'Are you sure you want to delete the environment variable?',
undefined,
true,
);
await balena.pine.delete({
resource: options.device
? options.config
? 'device_config_variable'
: 'device_environment_variable'
: options.config
? 'application_config_variable'
: 'application_environment_variable',
resource: ec.getVarResourceName(opt.config, opt.device, opt.service),
id: params.id,
});
}

110
lib/utils/env-common.ts Normal file
View File

@ -0,0 +1,110 @@
/**
* @license
* Copyright 2019 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 { flags } from '@oclif/command';
import { stripIndent } from 'common-tags';
import * as _ from 'lodash';
import { ExpectedError } from '../errors';
type IBooleanFlag<T> = import('@oclif/parser/lib/flags').IBooleanFlag<T>;
export const booleanConfig: IBooleanFlag<boolean> = flags.boolean({
char: 'c',
description:
'select a configuration variable (may be used together with the --device option)',
default: false,
exclusive: ['service'],
});
export const booleanDevice: IBooleanFlag<boolean> = flags.boolean({
char: 'd',
description:
'select a device-specific variable instead of an application (fleet) variable',
default: false,
});
export const booleanService: IBooleanFlag<boolean> = flags.boolean({
char: 's',
description:
'select a service variable (may be used together with the --device option)',
default: false,
exclusive: ['config'],
});
export const rmRenameHelp = stripIndent`
Variables are selected by their database ID (as reported by the 'balena envs'
command) and one of six database "resource types":
- application (fleet) environment variable
- application (fleet) configuration variable (--config)
- application (fleet) service variable (--service)
- device environment variable (--device)
- device configuration variable (--device --config)
- device service variable (--device --service)
The --device option selects a device-specific variable instead of an application
(fleet) variable.
The --config option selects a configuration variable. Configuration variable
names typically start with the 'BALENA_' or 'RESIN_' prefixes and are used to
configure balena platform features.
The --service option selects a service variable, which is an environment variable
that applies to a specifc service (application container) in a microservices
(multicontainer) application.
The --service and --config options cannot be used together, but they can be
used alongside the --device option to select a device-specific service or
configuration variable.
`;
/**
* Return an API database resource name like 'device_config_variable' or
* 'service_environment_variable' given three boolean arguments.
* @param isConfig Whether the resource is a configuration variable
* @param isDevice Whether the resource is a device variable
* @param isService Whether the resource is a service variable
*/
export function getVarResourceName(
isConfig: boolean,
isDevice: boolean,
isService: boolean,
): string {
return isDevice
? isConfig
? 'device_config_variable'
: isService
? 'device_service_environment_variable'
: 'device_environment_variable'
: isConfig
? 'application_config_variable'
: isService
? 'service_environment_variable'
: 'application_environment_variable';
}
/**
* Check that the given string looks like and parses like a decimal integer,
* and return the parsed value.
*/
export function parseDbId(id: string): number {
if (/^[\d]+$/.exec(id) == null) {
throw new ExpectedError("The variable's ID must be an integer");
}
return Number(id);
}

View File

@ -60,7 +60,7 @@ Additional commands:
devices supported list all supported devices
env add <name> [value] add an environment or config variable to an application, device or service
env rename <id> <value> change the value of an environment variable for an app or device
env rm <id> remove an environment variable from an application or device
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
key <id> list a single ssh key
key add <name> [path] add a SSH key to balena