exosphere-cli 2.3.0__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/PKG-INFO +1 -1
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/pyproject.toml +1 -1
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/providers/api.py +24 -2
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/providers/freebsd.py +19 -1
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/LICENSE +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/README.md +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/__init__.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/cli.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/commands/__init__.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/commands/config.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/commands/connections.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/commands/host.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/commands/inventory.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/commands/report.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/commands/sudo.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/commands/ui.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/commands/utils.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/commands/version.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/config.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/context.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/data.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/database.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/errors.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/fspaths.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/inventory.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/main.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/migrations.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/objects.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/pipelining.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/providers/__init__.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/providers/debian.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/providers/factory.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/providers/openbsd.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/providers/redhat.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/repl.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/reporting.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/schema/__init__.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/schema/host-report.schema.json +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/security.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/setup/__init__.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/setup/detect.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/templates/report.html.j2 +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/templates/report.md.j2 +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/templates/report.txt.j2 +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/ui/__init__.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/ui/app.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/ui/context.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/ui/dashboard.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/ui/elements.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/ui/inventory.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/ui/logs.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/ui/messages.py +0 -0
- {exosphere_cli-2.3.0 → exosphere_cli-2.4.0}/src/exosphere/ui/style.tcss +0 -0
|
@@ -6,13 +6,23 @@ well as helper functions and decorators to be used by package manager
|
|
|
6
6
|
provider implementations.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
import functools
|
|
9
10
|
import logging
|
|
10
11
|
from abc import ABC, abstractmethod
|
|
11
12
|
from collections.abc import Callable
|
|
12
13
|
|
|
13
14
|
from fabric import Connection
|
|
15
|
+
from invoke.exceptions import AuthFailure
|
|
14
16
|
|
|
15
17
|
from exosphere.data import Update
|
|
18
|
+
from exosphere.errors import DataRefreshError
|
|
19
|
+
|
|
20
|
+
_SUDO_AUTH_FAILURE_MESSAGE = (
|
|
21
|
+
"Sudo failed: "
|
|
22
|
+
"Ensure the user is configured with passwordless sudo. "
|
|
23
|
+
"You can use 'exosphere sudo generate' to produce a sudoers snippet for this host. "
|
|
24
|
+
"See: https://exosphere.readthedocs.io/en/stable/connections.html#id1"
|
|
25
|
+
)
|
|
16
26
|
|
|
17
27
|
|
|
18
28
|
def requires_sudo(func: Callable) -> Callable:
|
|
@@ -23,9 +33,21 @@ def requires_sudo(func: Callable) -> Callable:
|
|
|
23
33
|
it requires sudo privileges to execute. You should add it to any
|
|
24
34
|
method that requires elevated privileges, i.e. whenever you are
|
|
25
35
|
using 'cx.sudo()' instead of 'cx.run()'.
|
|
36
|
+
|
|
37
|
+
Additionally, the decorator provides enhanced error handling for
|
|
38
|
+
sudo related failures, presenting a clear message about sudo policies
|
|
39
|
+
and sudoers configuration when an AuthFailure or related exception occurs.
|
|
26
40
|
"""
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
|
|
42
|
+
@functools.wraps(func)
|
|
43
|
+
def wrapper(*args: object, **kwargs: object) -> object:
|
|
44
|
+
try:
|
|
45
|
+
return func(*args, **kwargs)
|
|
46
|
+
except AuthFailure as e:
|
|
47
|
+
raise DataRefreshError(_SUDO_AUTH_FAILURE_MESSAGE) from e
|
|
48
|
+
|
|
49
|
+
setattr(wrapper, "__requires_sudo", True)
|
|
50
|
+
return wrapper
|
|
29
51
|
|
|
30
52
|
|
|
31
53
|
class PkgManager(ABC):
|
|
@@ -26,6 +26,7 @@ class Pkg(PkgManager):
|
|
|
26
26
|
|
|
27
27
|
SUDOERS_COMMANDS: list[str] | None = [
|
|
28
28
|
"/usr/sbin/pkg update -q",
|
|
29
|
+
"/usr/sbin/pkg audit -qF",
|
|
29
30
|
]
|
|
30
31
|
|
|
31
32
|
def __init__(self) -> None:
|
|
@@ -41,7 +42,11 @@ class Pkg(PkgManager):
|
|
|
41
42
|
"""
|
|
42
43
|
Synchronize the package repository.
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
It will also download the latest version of the vuln.xml
|
|
46
|
+
database to check for security updates.
|
|
47
|
+
|
|
48
|
+
This method is equivalent to running 'pkg update -q', followed
|
|
49
|
+
by 'pkg audit -qF'.
|
|
45
50
|
|
|
46
51
|
:param cx: Fabric Connection object
|
|
47
52
|
:return: True if synchronization is successful, False otherwise.
|
|
@@ -56,6 +61,19 @@ class Pkg(PkgManager):
|
|
|
56
61
|
)
|
|
57
62
|
return False
|
|
58
63
|
|
|
64
|
+
# Sync vulnerability data via pkg audit -qF, which forces a download
|
|
65
|
+
# of the vuln.xml database. We do not store or parse the output, as
|
|
66
|
+
# the cost of running it a second time in get_updates() is negligible,
|
|
67
|
+
# and will be a local operation anyways.
|
|
68
|
+
self.logger.debug("Synchronizing vuln.xml via pkg audit")
|
|
69
|
+
audit_result = cx.sudo("/usr/sbin/pkg audit -qF", hide=True, warn=True)
|
|
70
|
+
|
|
71
|
+
if audit_result.failed and audit_result.stderr:
|
|
72
|
+
self.logger.error(
|
|
73
|
+
f"Failed to synchronize vuln.xml via pkg audit: {audit_result.stderr}"
|
|
74
|
+
)
|
|
75
|
+
return False
|
|
76
|
+
|
|
59
77
|
self.logger.debug("FreeBSD pkg repositories synchronized successfully")
|
|
60
78
|
|
|
61
79
|
return True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|