Skip to content
Merged
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
14 changes: 13 additions & 1 deletion src/cfengine_cli/cfengine_wrapper/arg_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
)


def _add_index_arg(parser: argparse.ArgumentParser):
parser.add_argument(
"--index",
help="Specify alternate index (HTTPS URL or relative path to JSON file)",
type=str,
default=None,
)


def parse_wrapper_args(subp: argparse._SubParsersAction):
update_parser = subp.add_parser(
"update",
Expand All @@ -20,7 +29,7 @@ def parse_wrapper_args(subp: argparse._SubParsersAction):
update_parser.add_argument(
"to_update",
nargs="*",
help="Directory of cfbs-project to update",
help="Module(s) to update (all modules if omitted)",
)
remove_parser = subp.add_parser(
"remove",
Expand All @@ -43,6 +52,7 @@ def parse_wrapper_args(subp: argparse._SubParsersAction):
nargs="+",
help="Module(s) for which to add",
)
_add_index_arg(add_parser)
search_parser = subp.add_parser(
"search",
help="Searches the build-index for specified module(s)",
Expand All @@ -53,6 +63,7 @@ def parse_wrapper_args(subp: argparse._SubParsersAction):
nargs="+",
help="Module(s) for which to lookup",
)
_add_index_arg(search_parser)

input_parser = subp.add_parser(
"input",
Expand Down Expand Up @@ -84,6 +95,7 @@ def parse_wrapper_args(subp: argparse._SubParsersAction):
nargs="*",
help="Module(s) for which you would like more info, utilizes cfbs `info` function",
)
_add_index_arg(moduleinfo_parser)

show_parser = subp.add_parser(
"show", help="Shows your saved host-groups or info about a specified host"
Expand Down
25 changes: 18 additions & 7 deletions src/cfengine_cli/cfengine_wrapper/cfengine_commands.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os

from cfbs.cfbs_config import CFBSConfig
from cfbs.utils import is_cfbs_repo
from cfbs.validate import validate_index_string
from cfbs.commands import (
build_command,
info_command,
Expand Down Expand Up @@ -301,7 +303,14 @@ def show(target: list[str] | None = None) -> int:
return info(target)


def moduleinfo(modules: list[str]) -> int:
def _init_cfbs_config(index: str | None = None) -> None:
if index is not None:
validate_index_string(index)
CFBSConfig.get_instance(index=index)


def moduleinfo(modules: list[str], index: str | None = None) -> int:
_init_cfbs_config(index)
if modules != []:
return info_command(modules)
if not is_cfbs_repo():
Expand All @@ -318,17 +327,19 @@ def cfbs_input(modules: list[str]) -> int:
return input_command(modules, "cfengine input")


def cfbs_add(modules: list[str]) -> int:
return add_command(modules, "cfengine input")
def cfbs_add(modules: list[str], index: str | None = None) -> int:
_init_cfbs_config(index)
return add_command(modules, "cfengine add")


def cfbs_remove(modules: list[str] | None = None) -> int:
return remove_command(modules, "cfengine input")
def cfbs_remove(modules: list[str]) -> int:
return remove_command(modules)


def cfbs_update(to_update) -> int:
def cfbs_update(to_update: list[str]) -> int:
return update_command(to_update)


def cfbs_search(modules: list[str]) -> int:
def cfbs_search(modules: list[str], index: str | None = None) -> int:
_init_cfbs_config(index)
return search_command(modules)
26 changes: 21 additions & 5 deletions src/cfengine_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@
validate_deploy_args,
validate_destroy_args,
)
from cfbs.utils import CFBSProgrammerError
from cfbs.utils import (
CFBSProgrammerError,
CFBSExitError,
CFBSUserError,
CFBSNetworkError,
CFBSValidationError,
)
from cfbs.git import CFBSGitError


def _get_arg_parser():
Expand Down Expand Up @@ -248,11 +255,11 @@ def run_command_with_args(args) -> int:
if args.command == "input":
return cfengine_commands.cfbs_input(args.module)
if args.command == "add":
return cfengine_commands.cfbs_add(args.module)
return cfengine_commands.cfbs_add(args.module, args.index)
if args.command == "remove":
return cfengine_commands.cfbs_remove(args.module)
if args.command == "search":
return cfengine_commands.cfbs_search(args.module)
return cfengine_commands.cfbs_search(args.module, args.index)
if args.command == "update":
return cfengine_commands.cfbs_update(args.to_update)
if args.command == "format":
Expand Down Expand Up @@ -363,7 +370,7 @@ def run_command_with_args(args) -> int:
if args.command == "show":
return cfengine_commands.show(args.hosts)
if args.command == "moduleinfo":
return cfengine_commands.moduleinfo(args.modules)
return cfengine_commands.moduleinfo(args.modules, args.index)
if args.command == "connect":
return cfengine_commands.connect(args.hosts)
raise UserError(f"Unknown command: '{args.command}'")
Expand Down Expand Up @@ -429,7 +436,16 @@ def main():
exit_code = _main()
assert type(exit_code) is int
sys.exit(exit_code)
except (UserError, CFRUserError, CFRExitError) as e:
except (
UserError,
CFRUserError,
CFRExitError,
CFBSExitError,
CFBSUserError,
CFBSNetworkError,
CFBSValidationError,
CFBSGitError,
) as e:
print(str(e))
sys.exit(-1)
# Exceptions below are not expected, print extra info:
Expand Down
77 changes: 77 additions & 0 deletions tests/shell/008-cfbs-index.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/bin/bash

set -e
set -x

# Setup: a cfbs project (without git) and a custom index in a temp directory
tmpdir=$(mktemp -d)
trap "rm -rf $tmpdir" EXIT
cd "$tmpdir"

cat > cfbs.json <<EOF
{
"name": "Example project",
"description": "Example description",
"type": "policy-set",
"git": false,
"build": []
}
EOF

cat > custom.json <<EOF
{
"name": "custom",
"type": "index",
"index": {
"my-module": {
"description": "Module only found in the custom index",
"tags": ["experimental"],
"repo": "https://github.com/cfengine/modules",
"by": "https://github.com/cfengine",
"version": "1.0.0",
"commit": "e603b586e4028364ceea234f3b71c6e5d78b811e",
"subdirectory": "management/autorun",
"steps": ["json def.json def.json"]
}
}
}
EOF

# --index is available for commands which look up modules in an index
cfengine add -h | grep -- "--index"
cfengine search -h | grep -- "--index"
cfengine moduleinfo -h | grep -- "--index"

# ...but not for commands which only operate on the project
for command in update remove input; do
if cfengine $command my-module --index ./custom.json; then
echo "FAIL: expected '--index' to be rejected by 'cfengine $command'"
exit 1
fi
done

# Search and moduleinfo find the module in the custom index
cfengine search my-module --index ./custom.json | grep "my-module - Module only found in the custom index"
cfengine moduleinfo my-module --index ./custom.json | grep "Module only found in the custom index"

# An invalid index string gives an error, not a backtrace
output=$(cfengine search my-module --index custom.json 2>&1) && exit 1
echo "$output" | grep 'must be a URL (starting with https://) or relative path (starting with ./)'
if echo "$output" | grep "Traceback"; then
exit 1
fi

# Adding from the custom index records the index on the module,
# but does not change the index of the project
cfengine add my-module --index ./custom.json
grep '"name": "my-module"' cfbs.json
grep '"index": "./custom.json"' cfbs.json
grep '"added_by": "cfengine add"' cfbs.json
[ "$(grep -c '"index"' cfbs.json)" = "1" ]

# Remove works without an index (newline accepts the default "yes" in the prompt)
echo | cfengine remove my-module
if grep "my-module" cfbs.json; then
echo "FAIL: expected my-module to be removed from cfbs.json"
exit 1
fi
Loading