Skip to content

Commit

Permalink
Add better option grouping
Browse files Browse the repository at this point in the history
  • Loading branch information
Akm0d committed Sep 3, 2024
1 parent 91c3143 commit b06e0fd
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 24 deletions.
14 changes: 11 additions & 3 deletions src/soluble/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,31 +44,39 @@
},
}

GROUP = "Soluble Options"

CLI_CONFIG = {
"bootstrap": {
"action": "store_true",
"subcommands": ["_global_"],
"group": GROUP,
},
"escalate": {
"action": "store_true",
"subcommands": ["_global_"],
"group": GROUP,
},
"roster_file": {"options": ["-R"]},
"roster_file": {"options": ["-R"], "group": GROUP},
"ssh_target": {
"positional": True,
"display_priority": 0,
"subcommands": [],
"help": "Target for the salt-ssh command. This is typically a minion ID, wildcard, or grain.",
"group": GROUP,
},
"salt_config_dir": {},
"salt_config_dir": {"group": GROUP},
"salt_bin": {
"subcommands": ["_global_"],
"group": GROUP,
},
"salt_key_bin": {
"subcommands": ["_global_"],
"group": GROUP,
},
}

SALT_SSH_GROUP = "Salt-SSH Options"
SALT_SSH_OPTIONS = {}
for name, opt in all_opts.items():
if name in CLI_CONFIG:
Expand All @@ -86,7 +94,7 @@
action=opt.action if "store" in opt.action else None,
nargs=opt.nargs,
options=opt._long_opts + opt._short_opts,
group="Salt-SSH",
group=SALT_SSH_GROUP,
)

CLI_CONFIG.update(SALT_SSH_OPTIONS)
Expand Down
4 changes: 0 additions & 4 deletions src/soluble/salt/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,9 @@ async def command(hub, name: str, action: Literal["-a", "-d"]):

process = await hub.lib.asyncio.create_subprocess_shell(
command,
stdout=hub.lib.asyncio.subprocess.PIPE,
)

stdout, _ = await process.communicate()
retcode = await process.wait()
if retcode != 0:
raise ChildProcessError(f"Failed to accept minion keys")
for line in stdout.splitlines():
hub.log.debug(line)
return retcode
14 changes: 11 additions & 3 deletions src/soluble/salt/ssh.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
async def run_command(
hub, name: str, command: str, *, capture_output: bool = True
hub,
name: str,
command: str,
*,
capture_output: bool = True,
hard_fail: bool = True,
) -> dict[str, object]:
"""Run a salt-ssh command asynchronously, handle all prompts, and return the output."""
target = hub.soluble.RUN[name].ssh_target
Expand Down Expand Up @@ -31,15 +36,18 @@ async def run_command(
process = await hub.lib.asyncio.create_subprocess_shell(
full_command,
stdout=stdout,
stderr=hub.lib.asyncio.subprocess.PIPE,
# stderr=hub.lib.asyncio.subprocess.PIPE,
)

# Wait for the process to complete and capture stdout at the end
stdout, _ = await process.communicate()
returncode = await process.wait()

if returncode != 0:
raise ChildProcessError(f"Command failed: {full_command}")
if hard_fail:
raise ChildProcessError(f"Command failed: {full_command}")
else:
return

if not capture_output:
return
Expand Down
5 changes: 3 additions & 2 deletions src/soluble/soluble/init.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from soluble.conf import CLI_CONFIG
from soluble.conf import SALT_SSH_GROUP
from soluble.conf import SUBCOMMANDS


Expand Down Expand Up @@ -48,7 +49,7 @@ def cli(hub):

# Turn salt-ssh opts into a string
for name, opts in CLI_CONFIG.items():
if opts.get("group", "").lower() != "salt-ssh":
if opts.get("group") != SALT_SSH_GROUP:
continue

value = kwargs.pop(name, None)
Expand Down Expand Up @@ -121,7 +122,7 @@ async def setup(hub, name: str):
async def run(hub, name: str) -> int:
"""This is where a soluble plugin runs its primary function"""
hub.log.info("Soluble run")
await hub.salt.ssh.run_command(name, f"grains.items", capture_output=False)
await hub.salt.ssh.run_command(name, f"test.ping", capture_output=False)
return 0


Expand Down
3 changes: 2 additions & 1 deletion src/soluble_master/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
"dyne": "soluble",
},
}
GROUP = "Soluble Master"

CLI_CONFIG = {
"master_config": {"subcommands": ["master"]},
"master_config": {"subcommands": ["master"], "group": GROUP},
}

DYNE = {"soluble": ["soluble"]}
4 changes: 4 additions & 0 deletions src/soluble_minion/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
},
}

GROUP = "Soluble Minion"

CLI_CONFIG = {
"minion_config": {"subcommands": ["minion"]},
"salt_command": {
Expand All @@ -14,6 +16,7 @@
"subcommands": ["minion"],
"help": "The salt command to run on the ephemeral nodes",
"dyne": "soluble",
"group": GROUP,
},
"salt_options": {
"positional": True,
Expand All @@ -22,6 +25,7 @@
"subcommands": ["minion"],
"help": "Additional options to be passed to the salt command",
"dyne": "soluble",
"group": GROUP,
},
}

Expand Down
14 changes: 9 additions & 5 deletions src/soluble_minion/soluble/minion.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,25 @@ async def teardown(hub, name: str):
# Stop the Salt minion service
hub.log.info("Stopping salt-minion service on target(s)...")
await hub.salt.ssh.run_command(
name, "state.single service.disabled name=salt-minion"
name, "state.single service.disabled name=salt-minion", hard_fail=False
)
await hub.salt.ssh.run_command(
name, "state.single service.dead name=salt-minion", hard_fail=False
)
await hub.salt.ssh.run_command(name, "state.single service.dead name=salt-minion")

# Uninstall Salt from the target
hub.log.info("Uninstalling Salt from target(s)...")
await hub.salt.ssh.run_command(name, "state.single pkg.removed name=salt-minion")
await hub.salt.ssh.run_command(
name, "state.single pkg.removed name=salt-minion", hard_fail=False
)

# Remove the minion configuration file
hub.log.info("Removing minion configuration from target(s)...")
await hub.salt.ssh.run_command(
name, "state.single file.absent name=/etc/salt/minion"
name, "state.single file.absent name=/etc/salt/minion", hard_fail=False
)
await hub.salt.ssh.run_command(
name, "state.single file.absent name=/etc/salt/minion_id"
name, "state.single file.absent name=/etc/salt/minion_id", hard_fail=False
)

hub.log.info("Destroy ephemeral minion key(s) on Salt master...")
Expand Down
8 changes: 4 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ def integration_hub():
hub = pop.hub.Hub()
hub.pop.sub.add("tests.helpers", subname="test")
hub.pop.sub.add(dyne_name="soluble")

hub.pop.sub.add(python_import="asyncio", sub=hub.lib)
hub.pop.sub.add(python_import="asyncssh", sub=hub.lib)
hub.pop.sub.add(python_import="docker", sub=hub.lib)
hub.pop.sub.add(python_import="pathlib", sub=hub.lib)
hub.pop.sub.add(python_import="pop", sub=hub.lib)
hub.pop.sub.add(python_import="pytest", sub=hub.lib)
hub.pop.sub.add(python_import="pwd", sub=hub.lib)
hub.pop.sub.add(python_import="uuid", sub=hub.lib)
hub.pop.sub.add(python_import="sys", sub=hub.lib)
hub.pop.sub.add(python_import="socket", sub=hub.lib)
hub.pop.sub.add(python_import="tempfile", sub=hub.lib)

with mock.patch("sys.argv", ["soluble"]):
hub.pop.config.load(["soluble"], cli="soluble", parse_cli=False)
hub.pop.config.load(["soluble"], cli="soluble", parse_cli=False)

yield hub
with mock.patch("sys.exit"):
yield hub


@pytest.fixture(scope="function", autouse=True)
Expand Down
9 changes: 7 additions & 2 deletions tests/soluble/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@


def test_help(hub):
with mock.patch("sys.argv", ["soluble"]):
hub.soluble.init.cli()
with mock.patch("sys.argv", ["soluble", "--help"]):
hub.pop.config.load(["soluble"], cli="soluble")


def test_sub_help(hub):
with mock.patch("sys.argv", ["soluble", "init", "--help"]):
hub.pop.config.load(["soluble"], cli="soluble")


async def test_cli(hub, salt_master):
Expand Down
10 changes: 10 additions & 0 deletions tests/soluble/test_master.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from unittest import mock


def test_help(hub):
with mock.patch("sys.argv", ["soluble", "master", "--help"]):
hub.pop.config.load(["soluble"], cli="soluble")


async def test_cli(hub):
...
11 changes: 11 additions & 0 deletions tests/soluble/test_minion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from unittest import mock


def test_help(hub):
with mock.patch("sys.argv", ["soluble", "minion", "--help"]):
hub.pop.config.load(["soluble"], cli="soluble")


async def test_cli(hub, salt_master):
await hub.test.container.create()
await hub.test.cmd.run("minion", "test.ping")

0 comments on commit b06e0fd

Please sign in to comment.