Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: pk secrets env command #505

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 62 additions & 12 deletions src/bin/secrets/CommandEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,68 @@
// import * as binUtils from '../utils';
// import * as CLIErrors from '../errors';
// import * as grpcErrors from '../../grpc/errors';

// import CommandPolykey from '../CommandPolykey';
// import * as binOptions from '../utils/options';

// class CommandEnv extends CommandPolykey {
// constructor(...args: ConstructorParameters<typeof CommandPolykey>) {
// super(...args);
// this.name('env');
// this.description('Secrets Env');
import type PolykeyClient from '../../PolykeyClient';
import type * as agentPB from '../../proto/js/polykey/v1/agent/agent_pb';
import CommandPolykey from '../CommandPolykey';
import * as binUtils from '../utils';
import * as binOptions from '../utils/options';
import * as binProcessors from '../utils/processors';

class CommandEnv extends CommandPolykey {
constructor(...args: ConstructorParameters<typeof CommandPolykey>) {
super(...args);
this.name('env');
this.description('Run a program with secrets injected into its environment');
this.option(
'-ie, --ignore-environment',
'Start with an empty environment',
);
this.option(
'-ee, --export-environment',
'Exports secrets into the shell',
);
this.argument(
'<[NAME=<vaultName>:<secretPath>]... <command> [arg]...>',
'List of secrets to inject and the command to run'
);
this.addOption(binOptions.nodeId);
this.addOption(binOptions.clientHost);
this.addOption(binOptions.clientPort);
this.action(async (args: Array<string>, options) => {
const secrets: Array<{
envName: string;
vaultName: string;
secretPath: string;
}> = [];
let argIndex = 0;
for (const arg of args) {
const secretMatches = arg.match(
/([A-Z]+)=([a-zA-Z0-9]+):([a-zA-Z0-9._\-\/\s]+)/
);
if (secretMatches != null) {
secrets.push({
envName: secretMatches[1],
vaultName: secretMatches[2],
secretPath: secretMatches[3],
});
} else {
break;
}
argIndex++;
}
console.log(secrets);
const commandArgs = args.slice(argIndex);
console.log(commandArgs);


// console.log(args);
// console.log(options);
});


// this.option(
// '--command <command>',
// 'In the environment of the derivation, run the shell command cmd in an interactive shell (Use --run to use a non-interactive shell instead)',
Expand All @@ -24,17 +77,14 @@
// '--run <run>',
// 'In the environment of the derivation, run the shell command cmd in a non-interactive shell, meaning (among other things) that if you hit Ctrl-C while the command is running, the shell exits (Use --command to use an interactive shell instead)',
// );
// this.arguments(
// "Secrets to inject into env, of the format '<vaultName>:<secretPath>[=<variableName>]', you can also control what the environment variable will be called using '[<variableName>]' (defaults to upper, snake case of the original secret name)",
// );
// this.addOption(binOptions.nodeId);
// this.addOption(binOptions.clientHost);
// this.addOption(binOptions.clientPort);
// this.action(async (options, command) => {

// });
// }
// }
}
}

// export default CommandEnv;

Expand Down Expand Up @@ -176,4 +226,4 @@
// }
// });

// export default env;
export default CommandEnv;
4 changes: 2 additions & 2 deletions src/bin/secrets/CommandSecrets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import CommandCreate from './CommandCreate';
import CommandDelete from './CommandDelete';
import CommandDir from './CommandDir';
import CommandEdit from './CommandEdit';
// Import CommandEnv from './CommandEnv';
import CommandEnv from './CommandEnv';
import CommandGet from './CommandGet';
import CommandList from './CommandList';
import CommandMkdir from './CommandMkdir';
Expand All @@ -20,7 +20,7 @@ class CommandSecrets extends CommandPolykey {
this.addCommand(new CommandDelete(...args));
this.addCommand(new CommandDir(...args));
this.addCommand(new CommandEdit(...args));
// This.addCommand(new CommandEnv(...args));
this.addCommand(new CommandEnv(...args));
this.addCommand(new CommandGet(...args));
this.addCommand(new CommandList(...args));
this.addCommand(new CommandMkdir(...args));
Expand Down
15 changes: 7 additions & 8 deletions src/bin/utils/parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,17 @@ function parseCoreCount(v: string): number | undefined {
return parseInt(v);
}

function parseSecretPath(secretPath: string): [string, string, string?] {
function parseSecretPath(secretAddress: string): [string, string] {
// E.g. If 'vault1:a/b/c', ['vault1', 'a/b/c'] is returned
// If 'vault1:a/b/c=VARIABLE', ['vault1, 'a/b/c', 'VARIABLE'] is returned
const secretPathRegex =
/^([\w-]+)(?::)([\w\-\\\/\.\$]+)(?:=)?([a-zA-Z_][\w]+)?$/;
if (!secretPathRegex.test(secretPath)) {
const secretAddressRegex = /^([a-zA-Z0-9-_]+):([\w\-\\\/\.\$]+)$/;
const matches = secretAddress.match(secretAddressRegex);
if (matches == null) {
throw new commander.InvalidArgumentError(
`${secretPath} is not of the format <vaultName>:<directoryPath>`,
`${secretAddress} is not of the format <vaultName>:<secretPath>`,
);
}
const [, vaultName, directoryPath] = secretPath.match(secretPathRegex)!;
return [vaultName, directoryPath, undefined];
const [, vaultName, secretPath] = matches;
return [vaultName, secretPath];
}

export {
Expand Down