pyinfra 2.9.2__py2.py3-none-any.whl → 3.0__py2.py3-none-any.whl
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.
- pyinfra/api/__init__.py +3 -0
- pyinfra/api/arguments.py +265 -253
- pyinfra/api/arguments_typed.py +80 -0
- pyinfra/api/command.py +68 -53
- pyinfra/api/config.py +139 -32
- pyinfra/api/connect.py +1 -1
- pyinfra/api/connectors.py +7 -26
- pyinfra/api/deploy.py +21 -52
- pyinfra/api/exceptions.py +33 -8
- pyinfra/api/facts.py +102 -137
- pyinfra/api/host.py +150 -82
- pyinfra/api/inventory.py +21 -25
- pyinfra/api/operation.py +240 -198
- pyinfra/api/operations.py +102 -148
- pyinfra/api/state.py +137 -79
- pyinfra/api/util.py +79 -86
- pyinfra/connectors/base.py +147 -0
- pyinfra/connectors/chroot.py +160 -169
- pyinfra/connectors/docker.py +220 -237
- pyinfra/connectors/dockerssh.py +231 -253
- pyinfra/connectors/local.py +196 -208
- pyinfra/connectors/ssh.py +530 -613
- pyinfra/connectors/ssh_util.py +114 -0
- pyinfra/connectors/sshuserclient/client.py +5 -3
- pyinfra/connectors/terraform.py +86 -65
- pyinfra/connectors/util.py +211 -137
- pyinfra/connectors/vagrant.py +60 -53
- pyinfra/context.py +4 -2
- pyinfra/facts/apk.py +2 -0
- pyinfra/facts/apt.py +2 -0
- pyinfra/facts/brew.py +2 -0
- pyinfra/facts/bsdinit.py +2 -0
- pyinfra/facts/cargo.py +2 -0
- pyinfra/facts/choco.py +2 -0
- pyinfra/facts/deb.py +7 -2
- pyinfra/facts/dnf.py +2 -0
- pyinfra/facts/docker.py +19 -0
- pyinfra/facts/files.py +47 -32
- pyinfra/facts/gem.py +2 -0
- pyinfra/facts/git.py +3 -1
- pyinfra/facts/gpg.py +3 -1
- pyinfra/facts/hardware.py +34 -24
- pyinfra/facts/iptables.py +5 -3
- pyinfra/facts/launchd.py +2 -0
- pyinfra/facts/lxd.py +2 -0
- pyinfra/facts/mysql.py +13 -6
- pyinfra/facts/npm.py +1 -0
- pyinfra/facts/openrc.py +2 -0
- pyinfra/facts/pacman.py +6 -2
- pyinfra/facts/pip.py +2 -0
- pyinfra/facts/pkg.py +2 -0
- pyinfra/facts/pkgin.py +2 -0
- pyinfra/facts/postgres.py +168 -0
- pyinfra/facts/postgresql.py +6 -160
- pyinfra/facts/rpm.py +12 -9
- pyinfra/facts/runit.py +68 -0
- pyinfra/facts/selinux.py +3 -1
- pyinfra/facts/server.py +80 -36
- pyinfra/facts/snap.py +2 -0
- pyinfra/facts/systemd.py +31 -12
- pyinfra/facts/sysvinit.py +10 -10
- pyinfra/facts/upstart.py +2 -0
- pyinfra/facts/util/packaging.py +7 -4
- pyinfra/facts/vzctl.py +2 -0
- pyinfra/facts/xbps.py +2 -0
- pyinfra/facts/yum.py +2 -0
- pyinfra/facts/zypper.py +2 -0
- pyinfra/local.py +4 -5
- pyinfra/operations/apk.py +6 -4
- pyinfra/operations/apt.py +46 -65
- pyinfra/operations/brew.py +17 -22
- pyinfra/operations/bsdinit.py +9 -7
- pyinfra/operations/cargo.py +4 -2
- pyinfra/operations/choco.py +4 -2
- pyinfra/operations/dnf.py +19 -23
- pyinfra/operations/docker.py +339 -0
- pyinfra/operations/files.py +188 -386
- pyinfra/operations/gem.py +4 -2
- pyinfra/operations/git.py +24 -53
- pyinfra/operations/iptables.py +29 -35
- pyinfra/operations/launchd.py +6 -7
- pyinfra/operations/lxd.py +8 -13
- pyinfra/operations/mysql.py +62 -81
- pyinfra/operations/npm.py +9 -2
- pyinfra/operations/openrc.py +6 -4
- pyinfra/operations/pacman.py +7 -8
- pyinfra/operations/pip.py +25 -24
- pyinfra/operations/pkg.py +4 -2
- pyinfra/operations/pkgin.py +6 -4
- pyinfra/operations/postgres.py +349 -0
- pyinfra/operations/postgresql.py +18 -379
- pyinfra/operations/puppet.py +3 -1
- pyinfra/operations/python.py +8 -19
- pyinfra/operations/runit.py +182 -0
- pyinfra/operations/selinux.py +47 -44
- pyinfra/operations/server.py +111 -127
- pyinfra/operations/snap.py +4 -4
- pyinfra/operations/ssh.py +20 -33
- pyinfra/operations/systemd.py +19 -15
- pyinfra/operations/sysvinit.py +9 -16
- pyinfra/operations/upstart.py +9 -7
- pyinfra/operations/util/__init__.py +12 -0
- pyinfra/operations/util/docker.py +177 -0
- pyinfra/operations/util/files.py +24 -16
- pyinfra/operations/util/packaging.py +55 -57
- pyinfra/operations/util/service.py +39 -51
- pyinfra/operations/vzctl.py +12 -10
- pyinfra/operations/xbps.py +6 -4
- pyinfra/operations/yum.py +18 -22
- pyinfra/operations/zypper.py +12 -13
- pyinfra/version.py +5 -2
- {pyinfra-2.9.2.dist-info → pyinfra-3.0.dist-info}/METADATA +40 -41
- pyinfra-3.0.dist-info/RECORD +167 -0
- {pyinfra-2.9.2.dist-info → pyinfra-3.0.dist-info}/WHEEL +1 -1
- pyinfra-3.0.dist-info/entry_points.txt +11 -0
- pyinfra_cli/__main__.py +4 -3
- pyinfra_cli/commands.py +7 -2
- pyinfra_cli/exceptions.py +78 -42
- pyinfra_cli/inventory.py +40 -6
- pyinfra_cli/log.py +17 -3
- pyinfra_cli/main.py +133 -90
- pyinfra_cli/prints.py +95 -127
- pyinfra_cli/util.py +62 -29
- tests/test_api/test_api.py +2 -0
- tests/test_api/test_api_arguments.py +13 -13
- tests/test_api/test_api_deploys.py +28 -29
- tests/test_api/test_api_facts.py +60 -98
- tests/test_api/test_api_operations.py +101 -201
- tests/test_cli/test_cli.py +18 -49
- tests/test_cli/test_cli_deploy.py +11 -37
- tests/test_cli/test_cli_exceptions.py +50 -19
- tests/test_cli/util.py +1 -1
- tests/test_connectors/test_chroot.py +6 -6
- tests/test_connectors/test_docker.py +4 -4
- tests/test_connectors/test_dockerssh.py +38 -50
- tests/test_connectors/test_local.py +11 -12
- tests/test_connectors/test_ssh.py +105 -93
- tests/test_connectors/test_terraform.py +9 -15
- tests/test_connectors/test_util.py +24 -46
- tests/test_connectors/test_vagrant.py +7 -7
- pyinfra/api/operation.pyi +0 -117
- pyinfra/connectors/ansible.py +0 -171
- pyinfra/connectors/mech.py +0 -186
- pyinfra/connectors/pyinfrawinrmsession/__init__.py +0 -28
- pyinfra/connectors/winrm.py +0 -320
- pyinfra/facts/windows.py +0 -366
- pyinfra/facts/windows_files.py +0 -90
- pyinfra/operations/windows.py +0 -59
- pyinfra/operations/windows_files.py +0 -551
- pyinfra-2.9.2.dist-info/RECORD +0 -170
- pyinfra-2.9.2.dist-info/entry_points.txt +0 -14
- tests/test_connectors/test_ansible.py +0 -64
- tests/test_connectors/test_mech.py +0 -126
- tests/test_connectors/test_winrm.py +0 -76
- {pyinfra-2.9.2.dist-info → pyinfra-3.0.dist-info}/LICENSE.md +0 -0
- {pyinfra-2.9.2.dist-info → pyinfra-3.0.dist-info}/top_level.txt +0 -0
pyinfra/operations/selinux.py
CHANGED
|
@@ -1,21 +1,36 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Provides operations to set SELinux file contexts, booleans and port types.
|
|
3
3
|
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from enum import Enum
|
|
8
|
+
|
|
4
9
|
from pyinfra import host
|
|
5
|
-
from pyinfra.api import QuoteString, StringCommand, operation
|
|
10
|
+
from pyinfra.api import OperationValueError, QuoteString, StringCommand, operation
|
|
6
11
|
from pyinfra.facts.selinux import FileContext, FileContextMapping, SEBoolean, SEPort, SEPorts
|
|
7
12
|
from pyinfra.facts.server import Which
|
|
8
13
|
|
|
9
14
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
class Boolean(Enum):
|
|
16
|
+
ON = "on"
|
|
17
|
+
OFF = "off"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Protocol(Enum):
|
|
21
|
+
UDP = "udp"
|
|
22
|
+
TCP = "tcp"
|
|
23
|
+
SCTP = "sctp"
|
|
24
|
+
DCCP = "dccp"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@operation()
|
|
28
|
+
def boolean(bool_name: str, value: Boolean, persistent=False):
|
|
14
29
|
"""
|
|
15
30
|
Set the specified SELinux boolean to the desired state.
|
|
16
31
|
|
|
17
32
|
+ boolean: name of an SELinux boolean
|
|
18
|
-
+
|
|
33
|
+
+ value: desired state of the boolean
|
|
19
34
|
+ persistent: whether to write updated policy or not
|
|
20
35
|
|
|
21
36
|
Note: This operation requires root privileges.
|
|
@@ -27,29 +42,31 @@ def boolean(bool_name, value, persistent=False):
|
|
|
27
42
|
selinux.boolean(
|
|
28
43
|
name='Allow Apache to connect to LDAP server',
|
|
29
44
|
'httpd_can_network_connect',
|
|
30
|
-
|
|
45
|
+
Boolean.ON,
|
|
31
46
|
persistent=True
|
|
32
47
|
)
|
|
33
48
|
"""
|
|
34
|
-
_valid_states = ["on", "off"]
|
|
35
49
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
50
|
+
value_str: str
|
|
51
|
+
if value in ["on", "off"]: # compatibility with the old version
|
|
52
|
+
assert isinstance(value, str)
|
|
53
|
+
value_str = value
|
|
54
|
+
elif value is Boolean.ON:
|
|
55
|
+
value_str = "on"
|
|
56
|
+
elif value is Boolean.OFF:
|
|
57
|
+
value_str = "off"
|
|
58
|
+
else:
|
|
59
|
+
raise OperationValueError(f"Invalid value '{value}' for boolean operation")
|
|
40
60
|
|
|
41
|
-
if host.get_fact(SEBoolean, boolean=bool_name) !=
|
|
61
|
+
if host.get_fact(SEBoolean, boolean=bool_name) != value_str:
|
|
42
62
|
persist = "-P " if persistent else ""
|
|
43
|
-
yield StringCommand("setsebool", f"{persist}{bool_name}",
|
|
44
|
-
host.create_fact(SEBoolean, kwargs={"boolean": bool_name}, data=value)
|
|
63
|
+
yield StringCommand("setsebool", f"{persist}{bool_name}", value_str)
|
|
45
64
|
else:
|
|
46
|
-
host.noop(f"boolean '{bool_name}' already had the value '{
|
|
65
|
+
host.noop(f"boolean '{bool_name}' already had the value '{value_str}'")
|
|
47
66
|
|
|
48
67
|
|
|
49
|
-
@operation(
|
|
50
|
-
|
|
51
|
-
)
|
|
52
|
-
def file_context(path, se_type):
|
|
68
|
+
@operation()
|
|
69
|
+
def file_context(path: str, se_type: str):
|
|
53
70
|
"""
|
|
54
71
|
Set the SELinux type for the specified path to the specified value.
|
|
55
72
|
|
|
@@ -70,19 +87,12 @@ def file_context(path, se_type):
|
|
|
70
87
|
current = host.get_fact(FileContext, path=path) or {}
|
|
71
88
|
if se_type != current.get("type", ""):
|
|
72
89
|
yield StringCommand("chcon", "-t", se_type, QuoteString(path))
|
|
73
|
-
host.create_fact(
|
|
74
|
-
FileContext,
|
|
75
|
-
kwargs={"path": path},
|
|
76
|
-
data=dict(current, **{"type": se_type}),
|
|
77
|
-
)
|
|
78
90
|
else:
|
|
79
91
|
host.noop(f"file_context: '{path}' already had type '{se_type}'")
|
|
80
92
|
|
|
81
93
|
|
|
82
|
-
@operation(
|
|
83
|
-
|
|
84
|
-
)
|
|
85
|
-
def file_context_mapping(target, se_type=None, present=True):
|
|
94
|
+
@operation()
|
|
95
|
+
def file_context_mapping(target: str, se_type: str | None = None, present=True):
|
|
86
96
|
"""
|
|
87
97
|
Set the SELinux file context mapping for paths matching the target.
|
|
88
98
|
|
|
@@ -108,30 +118,21 @@ def file_context_mapping(target, se_type=None, present=True):
|
|
|
108
118
|
raise ValueError("se_type must have a valid value if present is set")
|
|
109
119
|
|
|
110
120
|
current = host.get_fact(FileContextMapping, target=target)
|
|
111
|
-
kwargs = {"target": target}
|
|
112
121
|
if present:
|
|
113
122
|
option = "-a" if len(current) == 0 else ("-m" if current.get("type") != se_type else "")
|
|
114
123
|
if option != "":
|
|
115
124
|
yield StringCommand("semanage", "fcontext", option, "-t", se_type, QuoteString(target))
|
|
116
|
-
host.create_fact(
|
|
117
|
-
FileContextMapping,
|
|
118
|
-
kwargs=kwargs,
|
|
119
|
-
data=dict(current, **{"type": se_type}),
|
|
120
|
-
)
|
|
121
125
|
else:
|
|
122
126
|
host.noop(f"mapping for '{target}' -> '{se_type}' already present")
|
|
123
127
|
else:
|
|
124
128
|
if len(current) > 0:
|
|
125
129
|
yield StringCommand("semanage", "fcontext", "-d", QuoteString(target))
|
|
126
|
-
host.create_fact(FileContextMapping, kwargs=kwargs, data={})
|
|
127
130
|
else:
|
|
128
131
|
host.noop(f"no existing mapping for '{target}'")
|
|
129
132
|
|
|
130
133
|
|
|
131
|
-
@operation(
|
|
132
|
-
|
|
133
|
-
)
|
|
134
|
-
def port(protocol, port_num, se_type=None, present=True):
|
|
134
|
+
@operation()
|
|
135
|
+
def port(protocol: Protocol | str, port_num: int, se_type: str | None = None, present=True):
|
|
135
136
|
"""
|
|
136
137
|
Set the SELinux type for the specified protocol and port.
|
|
137
138
|
|
|
@@ -148,12 +149,16 @@ def port(protocol, port_num, se_type=None, present=True):
|
|
|
148
149
|
|
|
149
150
|
selinux.port(
|
|
150
151
|
name='Allow Apache to provide service on port 2222',
|
|
151
|
-
|
|
152
|
+
Protocol.TCP,
|
|
152
153
|
2222,
|
|
153
154
|
'http_port_t',
|
|
154
155
|
)
|
|
155
156
|
"""
|
|
156
157
|
|
|
158
|
+
if protocol is Protocol:
|
|
159
|
+
assert isinstance(protocol, Protocol)
|
|
160
|
+
protocol = protocol.value
|
|
161
|
+
|
|
157
162
|
if present and (se_type is None):
|
|
158
163
|
raise ValueError("se_type must have a valid value if present is set")
|
|
159
164
|
|
|
@@ -178,9 +183,7 @@ def port(protocol, port_num, se_type=None, present=True):
|
|
|
178
183
|
host.noop(f"setype for '{protocol}/{port_num}' is already unset")
|
|
179
184
|
|
|
180
185
|
if (present and (option != "")) or (not present and (current != "")):
|
|
181
|
-
if direct_get:
|
|
182
|
-
host.create_fact(SEPort, kwargs={"protocol": protocol, "port": port_num}, data=new_type)
|
|
183
|
-
else:
|
|
186
|
+
if not direct_get:
|
|
184
187
|
if protocol not in port_info:
|
|
185
188
|
port_info[protocol] = {}
|
|
186
189
|
port_info[protocol][str(port_num)] = new_type
|