Skip to content

Commit

Permalink
cli help improvements and unification
Browse files Browse the repository at this point in the history
  • Loading branch information
Esgrove committed Oct 26, 2024
1 parent 9940fa0 commit e6a5396
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 30 deletions.
2 changes: 2 additions & 0 deletions python-pyo3/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ nursery = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
missing_errors_doc = "allow"
missing_panics_doc = "allow"
redundant_pub_crate = "allow"
too_many_arguments = "allow"
96 changes: 70 additions & 26 deletions python-pyo3/python/n_vault/vault.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def main(
help="Suppress additional output and error messages",
),
version: bool = typer.Option(
None,
False,
"--version",
"-v",
is_eager=True,
Expand All @@ -104,12 +104,12 @@ def main(
Global options available in all subcommands.
"""
if version:
# This gets version number from Rust project definition,
# Get the version number from the Rust project definition,
# which is also what pip / pypi uses.
print(f"Nitor Vault {nitor_vault.version()}")
raise typer.Exit()

# Initialize Config dataclass and store it in Typer context
# Store global config in Typer context
config = Config(
vault_stack=vault_stack,
region=region,
Expand All @@ -129,7 +129,7 @@ def all_keys(ctx: typer.Context):


@app.command(name="delete | d")
def delete(ctx: typer.Context, key: str):
def delete(ctx: typer.Context, key: str = typer.Argument(..., help="Key name to delete", show_default=False)):
"""Delete an existing key from the store"""
config: Config = ctx.obj
nitor_vault.delete(
Expand All @@ -144,7 +144,7 @@ def delete(ctx: typer.Context, key: str):

@app.command()
def describe(ctx: typer.Context):
"""Describe CloudFormation stack parameters for current configuration"""
"""Print CloudFormation stack parameters for current configuration"""
config: Config = ctx.obj
nitor_vault.describe(
config.vault_stack,
Expand All @@ -158,29 +158,29 @@ def describe(ctx: typer.Context):
@app.command(name="decrypt | y")
def decrypt(
ctx: typer.Context,
value: str = typer.Argument(
value: str | None = typer.Argument(
None,
help="Value to decrypt, use '-' for stdin",
allow_dash=True,
show_default=False,
),
value_argument: str = typer.Option(
value_argument: str | None = typer.Option(
None,
"-v",
"--value",
help="Value to decrypt, use '-' for stdin",
allow_dash=True,
show_default=False,
),
file: Path = typer.Option(
file: Path | None = typer.Option(
None,
"-f",
"--file",
help="File to decrypt, use '-' for stdin",
allow_dash=True,
show_default=False,
),
outfile: Path = typer.Option(
outfile: Path | None = typer.Option(
None,
"-o",
"--outfile",
Expand All @@ -206,29 +206,29 @@ def decrypt(
@app.command(name="encrypt | e")
def encrypt(
ctx: typer.Context,
value: str = typer.Argument(
value: str | None = typer.Argument(
None,
help="Value to encrypt, use '-' for stdin",
allow_dash=True,
show_default=False,
),
value_argument: str = typer.Option(
value_argument: str | None = typer.Option(
None,
"-v",
"--value",
help="Value to encrypt, use '-' for stdin",
allow_dash=True,
show_default=False,
),
file: Path = typer.Option(
file: Path | None = typer.Option(
None,
"-f",
"--file",
help="File to encrypt, use '-' for stdin",
allow_dash=True,
show_default=False,
),
outfile: Path = typer.Option(
outfile: Path | None = typer.Option(
None,
"-o",
"--outfile",
Expand All @@ -252,8 +252,12 @@ def encrypt(


@app.command()
def exists(ctx: typer.Context, key: str):
"""Check if a key exists"""
def exists(ctx: typer.Context, key: str = typer.Argument(..., help="Key name to check", show_default=False)):
"""
Check if a key exists
Exits with code 0 if the key exists, code 5 if it does *not* exist, and with code 1 for other errors.
"""
config: Config = ctx.obj
result = nitor_vault.exists(
key,
Expand All @@ -272,8 +276,13 @@ def exists(ctx: typer.Context, key: str):
def info(ctx: typer.Context):
"""Print vault information"""
config: Config = ctx.obj
typer.echo("Vault information")
typer.echo(f"{config}")
nitor_vault.info(
config.vault_stack,
config.region,
config.bucket,
config.key_arn,
config.prefix,
)


@app.command("id")
Expand All @@ -284,8 +293,19 @@ def caller_id(ctx: typer.Context):


@app.command(name="init | i")
def init(ctx: typer.Context, name: str | None = None):
"""Initialize a new KMS key and S3 bucket"""
def init(ctx: typer.Context, name: str | None = typer.Argument(None, help="Vault stack name", show_default=False)):
"""
Initialize a new KMS key and S3 bucket
Initialize a KMS key and an S3 bucket with roles for reading and writing on a fresh account via CloudFormation.
The account used must have rights to create the resources.
Usage examples:
- `vault init`
- `vault init "vault-name"`
- `vault --vault-stack "vault-name" init`
- `VAULT_STACK="vault-name" vault i`
"""
config: Config = ctx.obj
nitor_vault.init(name, config.vault_stack, config.region, config.bucket, config.quiet)

Expand All @@ -294,7 +314,7 @@ def init(ctx: typer.Context, name: str | None = None):
def lookup(
ctx: typer.Context,
key: str = typer.Argument(..., help="Key name to lookup", show_default=False),
outfile: Path = typer.Option(None, "-o", "--outfile", help="Optional output file", show_default=False),
outfile: Path | None = typer.Option(None, "-o", "--outfile", help="Optional output file", show_default=False),
):
"""Output secret value for given key"""
config: Config = ctx.obj
Expand All @@ -320,17 +340,17 @@ def status(ctx: typer.Context):
@app.command(name="store | s")
def store(
ctx: typer.Context,
key: str = typer.Argument(None, help="Key name to use for stored value", show_default=False),
value: str = typer.Argument(None, help="Value to store, use '-' for stdin", show_default=False),
value_argument: str = typer.Option(
key: str | None = typer.Argument(None, help="Key name to use for stored value", show_default=False),
value: str | None = typer.Argument(None, help="Value to store, use '-' for stdin", show_default=False),
value_argument: str | None = typer.Option(
None,
"-v",
"--value",
help="Value to store, use '-' for stdin",
allow_dash=True,
show_default=False,
),
file: Path = typer.Option(
file: Path | None = typer.Option(
None,
"-f",
"--file",
Expand All @@ -346,7 +366,20 @@ def store(
show_default=False,
),
):
"""Store a new key-value pair"""
"""
Store a new key-value pair
Store a new key-value pair in the vault.
You can provide the key and value directly, or specify a file to store.
Usage examples:
- Store a value: `vault store "my-key" "some value"`
- Store a value from args: `vault store mykey --value "some value"`
- Store from a file: `vault store mykey --file path/to/file.txt`
- Store from a file with filename as key: `vault store --file path/to/file.txt`
- Store from stdin: `echo "some data" | vault store mykey -`
- Store from stdin: `cat file.zip | vault store mykey --file -`
"""
if (value and value_argument) or (value_argument and file) or (value and file):
raise typer.BadParameter("Specify only one of positional value, '--value' or '--file'")

Expand All @@ -368,7 +401,18 @@ def store(

@app.command(name="update | u")
def update(ctx: typer.Context, name: str = typer.Option(None, help="Optional vault stack name", show_default=False)):
"""Update the vault CloudFormation stack"""
"""
Update the vault CloudFormation stack
Update the CloudFormation stack which declares all resources needed by the vault.
Usage examples:
- `vault update`
- `vault update "vault-name"`
- `vault u "vault-name"`
- `vault --vault-stack "vault-name" update`
- `VAULT_STACK="vault-name" vault u`
"""
config: Config = ctx.obj
nitor_vault.update(
name, config.vault_stack, config.region, config.bucket, config.key_arn, config.prefix, config.quiet
Expand Down
1 change: 1 addition & 0 deletions python-pyo3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const fn version() -> &'static str {
VERSION
}

#[allow(clippy::needless_pass_by_value)]
/// Convert `anyhow::Error` to `PyErr`
fn anyhow_to_py_err(err: anyhow::Error) -> PyErr {
PyRuntimeError::new_err(format!("{err:?}"))
Expand Down
11 changes: 7 additions & 4 deletions rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,12 @@ enum Command {

/// Delete an existing key from the store
#[command(short_flag('d'), long_flag("delete"), alias("d"))]
Delete { key: String },
Delete {
/// Key name to delete
key: String,
},

/// Describe CloudFormation stack parameters for current configuration.
/// Print CloudFormation stack parameters for current configuration.
// This value is useful for Lambdas as you can load the CloudFormation parameters from env.
#[command(long_flag("describe"))]
Describe {},
Expand Down Expand Up @@ -138,12 +141,12 @@ enum Command {
#[command(
long_flag("exists"),
long_about = "Check if the given key exists.\n\n\
It will exit with code 0 if the key exists,\n\
Exits with code 0 if the key exists,\n\
code 5 if it does *not* exist,\n\
and with code 1 for other errors."
)]
Exists {
/// Key name to lookup
/// Key name to check
key: String,
},

Expand Down

0 comments on commit e6a5396

Please sign in to comment.