pyinfra 0.11.dev3__py3-none-any.whl → 3.6__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/__init__.py +9 -12
- pyinfra/__main__.py +4 -0
- pyinfra/api/__init__.py +19 -3
- pyinfra/api/arguments.py +413 -0
- pyinfra/api/arguments_typed.py +79 -0
- pyinfra/api/command.py +274 -0
- pyinfra/api/config.py +222 -28
- pyinfra/api/connect.py +33 -13
- pyinfra/api/connectors.py +27 -0
- pyinfra/api/deploy.py +65 -66
- pyinfra/api/exceptions.py +73 -18
- pyinfra/api/facts.py +267 -200
- pyinfra/api/host.py +416 -50
- pyinfra/api/inventory.py +121 -160
- pyinfra/api/metadata.py +69 -0
- pyinfra/api/operation.py +432 -262
- pyinfra/api/operations.py +273 -260
- pyinfra/api/state.py +302 -248
- pyinfra/api/util.py +309 -369
- pyinfra/connectors/base.py +173 -0
- pyinfra/connectors/chroot.py +212 -0
- pyinfra/connectors/docker.py +405 -0
- pyinfra/connectors/dockerssh.py +297 -0
- pyinfra/connectors/local.py +238 -0
- pyinfra/connectors/scp/__init__.py +1 -0
- pyinfra/connectors/scp/client.py +204 -0
- pyinfra/connectors/ssh.py +727 -0
- pyinfra/connectors/ssh_util.py +114 -0
- pyinfra/connectors/sshuserclient/client.py +309 -0
- pyinfra/connectors/sshuserclient/config.py +102 -0
- pyinfra/connectors/terraform.py +135 -0
- pyinfra/connectors/util.py +417 -0
- pyinfra/connectors/vagrant.py +183 -0
- pyinfra/context.py +145 -0
- pyinfra/facts/__init__.py +7 -6
- pyinfra/facts/apk.py +22 -7
- pyinfra/facts/apt.py +117 -60
- pyinfra/facts/brew.py +100 -15
- pyinfra/facts/bsdinit.py +23 -0
- pyinfra/facts/cargo.py +37 -0
- pyinfra/facts/choco.py +47 -0
- pyinfra/facts/crontab.py +195 -0
- pyinfra/facts/deb.py +94 -0
- pyinfra/facts/dnf.py +48 -0
- pyinfra/facts/docker.py +96 -23
- pyinfra/facts/efibootmgr.py +113 -0
- pyinfra/facts/files.py +629 -58
- pyinfra/facts/flatpak.py +77 -0
- pyinfra/facts/freebsd.py +70 -0
- pyinfra/facts/gem.py +19 -6
- pyinfra/facts/git.py +59 -14
- pyinfra/facts/gpg.py +150 -0
- pyinfra/facts/hardware.py +313 -167
- pyinfra/facts/iptables.py +72 -62
- pyinfra/facts/launchd.py +44 -0
- pyinfra/facts/lxd.py +17 -4
- pyinfra/facts/mysql.py +122 -86
- pyinfra/facts/npm.py +17 -9
- pyinfra/facts/openrc.py +71 -0
- pyinfra/facts/opkg.py +246 -0
- pyinfra/facts/pacman.py +50 -7
- pyinfra/facts/pip.py +24 -7
- pyinfra/facts/pipx.py +82 -0
- pyinfra/facts/pkg.py +15 -6
- pyinfra/facts/pkgin.py +35 -0
- pyinfra/facts/podman.py +54 -0
- pyinfra/facts/postgres.py +178 -0
- pyinfra/facts/postgresql.py +6 -147
- pyinfra/facts/rpm.py +105 -0
- pyinfra/facts/runit.py +77 -0
- pyinfra/facts/selinux.py +161 -0
- pyinfra/facts/server.py +762 -285
- pyinfra/facts/snap.py +88 -0
- pyinfra/facts/systemd.py +139 -0
- pyinfra/facts/sysvinit.py +59 -0
- pyinfra/facts/upstart.py +35 -0
- pyinfra/facts/util/__init__.py +17 -0
- pyinfra/facts/util/databases.py +4 -6
- pyinfra/facts/util/packaging.py +37 -6
- pyinfra/facts/util/units.py +30 -0
- pyinfra/facts/util/win_files.py +99 -0
- pyinfra/facts/vzctl.py +20 -13
- pyinfra/facts/xbps.py +35 -0
- pyinfra/facts/yum.py +34 -40
- pyinfra/facts/zfs.py +77 -0
- pyinfra/facts/zypper.py +42 -0
- pyinfra/local.py +45 -83
- pyinfra/operations/__init__.py +12 -0
- pyinfra/operations/apk.py +99 -0
- pyinfra/operations/apt.py +496 -0
- pyinfra/operations/brew.py +232 -0
- pyinfra/operations/bsdinit.py +59 -0
- pyinfra/operations/cargo.py +45 -0
- pyinfra/operations/choco.py +61 -0
- pyinfra/operations/crontab.py +194 -0
- pyinfra/operations/dnf.py +213 -0
- pyinfra/operations/docker.py +492 -0
- pyinfra/operations/files.py +2014 -0
- pyinfra/operations/flatpak.py +95 -0
- pyinfra/operations/freebsd/__init__.py +12 -0
- pyinfra/operations/freebsd/freebsd_update.py +70 -0
- pyinfra/operations/freebsd/pkg.py +219 -0
- pyinfra/operations/freebsd/service.py +116 -0
- pyinfra/operations/freebsd/sysrc.py +92 -0
- pyinfra/operations/gem.py +48 -0
- pyinfra/operations/git.py +420 -0
- pyinfra/operations/iptables.py +312 -0
- pyinfra/operations/launchd.py +45 -0
- pyinfra/operations/lxd.py +69 -0
- pyinfra/operations/mysql.py +610 -0
- pyinfra/operations/npm.py +57 -0
- pyinfra/operations/openrc.py +63 -0
- pyinfra/operations/opkg.py +89 -0
- pyinfra/operations/pacman.py +82 -0
- pyinfra/operations/pip.py +206 -0
- pyinfra/operations/pipx.py +103 -0
- pyinfra/operations/pkg.py +71 -0
- pyinfra/operations/pkgin.py +92 -0
- pyinfra/operations/postgres.py +437 -0
- pyinfra/operations/postgresql.py +30 -0
- pyinfra/operations/puppet.py +41 -0
- pyinfra/operations/python.py +73 -0
- pyinfra/operations/runit.py +184 -0
- pyinfra/operations/selinux.py +190 -0
- pyinfra/operations/server.py +1100 -0
- pyinfra/operations/snap.py +118 -0
- pyinfra/operations/ssh.py +217 -0
- pyinfra/operations/systemd.py +150 -0
- pyinfra/operations/sysvinit.py +142 -0
- pyinfra/operations/upstart.py +68 -0
- pyinfra/operations/util/__init__.py +12 -0
- pyinfra/operations/util/docker.py +407 -0
- pyinfra/operations/util/files.py +247 -0
- pyinfra/operations/util/packaging.py +338 -0
- pyinfra/operations/util/service.py +46 -0
- pyinfra/operations/vzctl.py +137 -0
- pyinfra/operations/xbps.py +78 -0
- pyinfra/operations/yum.py +213 -0
- pyinfra/operations/zfs.py +176 -0
- pyinfra/operations/zypper.py +193 -0
- pyinfra/progress.py +44 -32
- pyinfra/py.typed +0 -0
- pyinfra/version.py +9 -1
- pyinfra-3.6.dist-info/METADATA +142 -0
- pyinfra-3.6.dist-info/RECORD +160 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.6.dist-info}/WHEEL +1 -2
- pyinfra-3.6.dist-info/entry_points.txt +12 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.6.dist-info/licenses}/LICENSE.md +1 -1
- pyinfra_cli/__init__.py +1 -0
- pyinfra_cli/cli.py +793 -0
- pyinfra_cli/commands.py +66 -0
- pyinfra_cli/exceptions.py +155 -65
- pyinfra_cli/inventory.py +233 -89
- pyinfra_cli/log.py +39 -43
- pyinfra_cli/main.py +26 -495
- pyinfra_cli/prints.py +215 -156
- pyinfra_cli/util.py +172 -105
- pyinfra_cli/virtualenv.py +25 -20
- pyinfra/api/connectors/__init__.py +0 -21
- pyinfra/api/connectors/ansible.py +0 -99
- pyinfra/api/connectors/docker.py +0 -178
- pyinfra/api/connectors/local.py +0 -169
- pyinfra/api/connectors/ssh.py +0 -402
- pyinfra/api/connectors/sshuserclient/client.py +0 -105
- pyinfra/api/connectors/sshuserclient/config.py +0 -90
- pyinfra/api/connectors/util.py +0 -63
- pyinfra/api/connectors/vagrant.py +0 -155
- pyinfra/facts/init.py +0 -176
- pyinfra/facts/util/files.py +0 -102
- pyinfra/hook.py +0 -41
- pyinfra/modules/__init__.py +0 -11
- pyinfra/modules/apk.py +0 -64
- pyinfra/modules/apt.py +0 -272
- pyinfra/modules/brew.py +0 -122
- pyinfra/modules/files.py +0 -711
- pyinfra/modules/gem.py +0 -30
- pyinfra/modules/git.py +0 -115
- pyinfra/modules/init.py +0 -344
- pyinfra/modules/iptables.py +0 -271
- pyinfra/modules/lxd.py +0 -45
- pyinfra/modules/mysql.py +0 -347
- pyinfra/modules/npm.py +0 -47
- pyinfra/modules/pacman.py +0 -60
- pyinfra/modules/pip.py +0 -99
- pyinfra/modules/pkg.py +0 -43
- pyinfra/modules/postgresql.py +0 -245
- pyinfra/modules/puppet.py +0 -20
- pyinfra/modules/python.py +0 -37
- pyinfra/modules/server.py +0 -524
- pyinfra/modules/ssh.py +0 -150
- pyinfra/modules/util/files.py +0 -52
- pyinfra/modules/util/packaging.py +0 -118
- pyinfra/modules/vzctl.py +0 -133
- pyinfra/modules/yum.py +0 -171
- pyinfra/pseudo_modules.py +0 -64
- pyinfra-0.11.dev3.dist-info/.DS_Store +0 -0
- pyinfra-0.11.dev3.dist-info/METADATA +0 -135
- pyinfra-0.11.dev3.dist-info/RECORD +0 -95
- pyinfra-0.11.dev3.dist-info/entry_points.txt +0 -3
- pyinfra-0.11.dev3.dist-info/top_level.txt +0 -2
- pyinfra_cli/__main__.py +0 -40
- pyinfra_cli/config.py +0 -92
- /pyinfra/{modules/util → connectors}/__init__.py +0 -0
- /pyinfra/{api/connectors → connectors}/sshuserclient/__init__.py +0 -0
pyinfra/modules/iptables.py
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
'''
|
|
2
|
-
The iptables modules handles iptables rules
|
|
3
|
-
'''
|
|
4
|
-
|
|
5
|
-
from pyinfra.api import operation
|
|
6
|
-
from pyinfra.api.exceptions import OperationError
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@operation
|
|
10
|
-
def chain(
|
|
11
|
-
state, host, name, present=True,
|
|
12
|
-
table='filter', policy=None, version=4,
|
|
13
|
-
):
|
|
14
|
-
'''
|
|
15
|
-
Add/remove/update iptables chains.
|
|
16
|
-
|
|
17
|
-
+ name: the name of the chain
|
|
18
|
-
+ present: whether the chain should exist
|
|
19
|
-
+ table: the iptables table this chain should belong to
|
|
20
|
-
+ policy: the policy this table should have
|
|
21
|
-
+ version: whether to target iptables or ip6tables
|
|
22
|
-
|
|
23
|
-
Policy:
|
|
24
|
-
These can only be applied to system chains (FORWARD, INPUT, OUTPUT, etc).
|
|
25
|
-
'''
|
|
26
|
-
|
|
27
|
-
chains = (
|
|
28
|
-
host.fact.iptables_chains(table)
|
|
29
|
-
if version == 4
|
|
30
|
-
else host.fact.ip6tables_chains(table)
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
command = 'iptables' if version == 4 else 'ip6tables'
|
|
34
|
-
command = '{0} -t {1}'.format(command, table)
|
|
35
|
-
|
|
36
|
-
# Doesn't exist but we want it?
|
|
37
|
-
if present and name not in chains:
|
|
38
|
-
yield '{0} -N {1}'.format(command, name)
|
|
39
|
-
|
|
40
|
-
if policy:
|
|
41
|
-
yield '{0} -P {1} {2}'.format(command, name, policy)
|
|
42
|
-
|
|
43
|
-
# Exists and we don't want it?
|
|
44
|
-
if not present and name in chains:
|
|
45
|
-
yield '{0} -X {1}'.format(command, name)
|
|
46
|
-
|
|
47
|
-
# Exists, we want it, but the policies don't match?
|
|
48
|
-
if present and name in chains and policy and chains[name] != policy:
|
|
49
|
-
yield '{0} -P {1} {2}'.format(command, name, policy)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@operation
|
|
53
|
-
def rule(
|
|
54
|
-
state, host, chain, jump, present=True,
|
|
55
|
-
table='filter', append=True, version=4,
|
|
56
|
-
# Core iptables filter arguments
|
|
57
|
-
protocol=None, not_protocol=None,
|
|
58
|
-
source=None, not_source=None,
|
|
59
|
-
destination=None, not_destination=None,
|
|
60
|
-
in_interface=None, not_in_interface=None,
|
|
61
|
-
out_interface=None, not_out_interface=None,
|
|
62
|
-
# After-rule arguments
|
|
63
|
-
to_destination=None, to_source=None, to_ports=None, log_prefix=None,
|
|
64
|
-
# Extras and extra shortcuts
|
|
65
|
-
destination_port=None, source_port=None, extras='',
|
|
66
|
-
):
|
|
67
|
-
'''
|
|
68
|
-
Add/remove iptables rules.
|
|
69
|
-
|
|
70
|
-
+ chain: the chain this rule should live in
|
|
71
|
-
+ jump: the target of the rule
|
|
72
|
-
+ table: the iptables table this rule should belong to
|
|
73
|
-
+ append: whether to append or insert the rule (if not present)
|
|
74
|
-
+ version: whether to target iptables or ip6tables
|
|
75
|
-
|
|
76
|
-
Iptables args:
|
|
77
|
-
|
|
78
|
-
+ protocol/not_protocol: filter by protocol (tcp or udp)
|
|
79
|
-
+ source/not_source: filter by source IPs
|
|
80
|
-
+ destination/not_destination: filter by destination IPs
|
|
81
|
-
+ in_interface/not_in_interface: filter by incoming interface
|
|
82
|
-
+ out_interface/not_out_interface: filter by outgoing interface
|
|
83
|
-
+ to_destination: where to route to when jump=DNAT
|
|
84
|
-
+ to_source: where to route to when jump=SNAT
|
|
85
|
-
+ to_ports: where to route to when jump=REDIRECT
|
|
86
|
-
+ log_prefix: prefix for the log of this rule when jump=LOG
|
|
87
|
-
|
|
88
|
-
Extras:
|
|
89
|
-
|
|
90
|
-
+ extras: a place to define iptables extension arguments (eg --limit, --physdev)
|
|
91
|
-
+ destination_port: destination port (requires protocol)
|
|
92
|
-
+ source_port: source port (requires protocol)
|
|
93
|
-
|
|
94
|
-
Examples:
|
|
95
|
-
|
|
96
|
-
.. code:: python
|
|
97
|
-
|
|
98
|
-
# Block SSH traffic
|
|
99
|
-
|
|
100
|
-
iptables.rule(
|
|
101
|
-
'INPUT', 'DROP',
|
|
102
|
-
destination_port=22
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
# NAT traffic on from 8.8.8.8:53 to 8.8.4.4:8080
|
|
107
|
-
|
|
108
|
-
iptables.rule(
|
|
109
|
-
'PREROUTING', 'DNAT', table='nat',
|
|
110
|
-
source='8.8.8.8', destination_port=53,
|
|
111
|
-
to_destination='8.8.4.4:8080'
|
|
112
|
-
)
|
|
113
|
-
'''
|
|
114
|
-
|
|
115
|
-
# These are only shortcuts for extras
|
|
116
|
-
if destination_port:
|
|
117
|
-
extras = '{0} --dport {1}'.format(extras, destination_port)
|
|
118
|
-
|
|
119
|
-
if source_port:
|
|
120
|
-
extras = '{0} --sport {1}'.format(extras, source_port)
|
|
121
|
-
|
|
122
|
-
# Convert the extras string into a set to enable comparison with the fact
|
|
123
|
-
extras_set = set(extras.split())
|
|
124
|
-
|
|
125
|
-
# When protocol is set, the extension is automagically added by iptables (which shows
|
|
126
|
-
# in iptables-save): http://ipset.netfilter.org/iptables-extensions.man.html
|
|
127
|
-
if protocol:
|
|
128
|
-
extras_set.add('-m')
|
|
129
|
-
extras_set.add(protocol)
|
|
130
|
-
|
|
131
|
-
# --dport and --sport do not work without a protocol (because they need -m [tcp|udp]
|
|
132
|
-
elif destination_port or source_port:
|
|
133
|
-
raise OperationError(
|
|
134
|
-
'iptables cannot filter by destination_port/source_port without a protocol',
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
# Verify NAT arguments, --to-destination only w/table=nat, jump=DNAT
|
|
138
|
-
if to_destination and (table != 'nat' or jump != 'DNAT'):
|
|
139
|
-
raise OperationError(
|
|
140
|
-
'iptables only supports to_destination on the nat table and the DNAT jump '
|
|
141
|
-
'(table={0}, jump={1})'.format(table, jump),
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
# As above, --to-source only w/table=nat, jump=SNAT
|
|
145
|
-
if to_source and (table != 'nat' or jump != 'SNAT'):
|
|
146
|
-
raise OperationError(
|
|
147
|
-
'iptables only supports to_source on the nat table and the SNAT jump '
|
|
148
|
-
'(table={0}, jump={1})'.format(table, jump),
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
# As above, --to-ports only w/table=nat, jump=REDIRECT
|
|
152
|
-
if to_ports and (table != 'nat' or jump != 'REDIRECT'):
|
|
153
|
-
raise OperationError(
|
|
154
|
-
'iptables only supports to_ports on the nat table and the REDIRECT jump '
|
|
155
|
-
'(table={0}, jump={1})'.format(table, jump),
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
# --log-prefix is only supported with jump=LOG
|
|
159
|
-
if log_prefix and jump != 'LOG':
|
|
160
|
-
raise OperationError(
|
|
161
|
-
'iptables only supports log_prefix with the LOG jump '
|
|
162
|
-
'(jump={0})'.format(jump),
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
definition = {
|
|
166
|
-
'chain': chain,
|
|
167
|
-
'jump': jump,
|
|
168
|
-
|
|
169
|
-
'protocol': protocol,
|
|
170
|
-
'source': source,
|
|
171
|
-
'destination': destination,
|
|
172
|
-
'in_interface': in_interface,
|
|
173
|
-
'out_interface': out_interface,
|
|
174
|
-
|
|
175
|
-
'not_protocol': not_protocol,
|
|
176
|
-
'not_source': not_source,
|
|
177
|
-
'not_destination': not_destination,
|
|
178
|
-
'not_in_interface': not_in_interface,
|
|
179
|
-
'not_out_interface': not_out_interface,
|
|
180
|
-
|
|
181
|
-
# These go *after* the jump argument
|
|
182
|
-
'log_prefix': log_prefix,
|
|
183
|
-
'to_destination': to_destination,
|
|
184
|
-
'to_source': to_source,
|
|
185
|
-
'to_ports': to_ports,
|
|
186
|
-
'extras': extras_set,
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
definition = {
|
|
190
|
-
key: (
|
|
191
|
-
'{0}/32'.format(value)
|
|
192
|
-
if (
|
|
193
|
-
'/' not in value
|
|
194
|
-
and key in ('source', 'not_source', 'destination', 'not_destination')
|
|
195
|
-
)
|
|
196
|
-
else value
|
|
197
|
-
)
|
|
198
|
-
for key, value in definition.items()
|
|
199
|
-
if value
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
rules = (
|
|
203
|
-
host.fact.iptables_rules(table)
|
|
204
|
-
if version == 4
|
|
205
|
-
else host.fact.ip6tables_rules(table)
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
action = None
|
|
209
|
-
|
|
210
|
-
# Definition doesn't exist and we want it
|
|
211
|
-
if present and definition not in rules:
|
|
212
|
-
action = '-A' if append else '-I'
|
|
213
|
-
|
|
214
|
-
# Definition exists and we don't want it
|
|
215
|
-
if not present and definition in rules:
|
|
216
|
-
action = '-D'
|
|
217
|
-
|
|
218
|
-
# Are we adding/removing a rule? Lets build it
|
|
219
|
-
if action:
|
|
220
|
-
args = [
|
|
221
|
-
'iptables' if version == 4 else 'ip6tables',
|
|
222
|
-
# Add the table
|
|
223
|
-
'-t', table,
|
|
224
|
-
# Add the action and target chain
|
|
225
|
-
action, chain,
|
|
226
|
-
]
|
|
227
|
-
|
|
228
|
-
if protocol:
|
|
229
|
-
args.extend(('-p', protocol))
|
|
230
|
-
|
|
231
|
-
if source:
|
|
232
|
-
args.extend(('-s', source))
|
|
233
|
-
|
|
234
|
-
if in_interface:
|
|
235
|
-
args.extend(('-i', in_interface))
|
|
236
|
-
|
|
237
|
-
if out_interface:
|
|
238
|
-
args.extend(('-o', out_interface))
|
|
239
|
-
|
|
240
|
-
if not_protocol:
|
|
241
|
-
args.extend(('!', '-p', not_protocol))
|
|
242
|
-
|
|
243
|
-
if not_source:
|
|
244
|
-
args.extend(('!', '-s', not_source))
|
|
245
|
-
|
|
246
|
-
if not_in_interface:
|
|
247
|
-
args.extend(('!', '-i', not_in_interface))
|
|
248
|
-
|
|
249
|
-
if not_out_interface:
|
|
250
|
-
args.extend(('!', '-o', not_out_interface))
|
|
251
|
-
|
|
252
|
-
if extras:
|
|
253
|
-
args.append(extras.strip())
|
|
254
|
-
|
|
255
|
-
# Add the jump
|
|
256
|
-
args.extend(('-j', jump))
|
|
257
|
-
|
|
258
|
-
if log_prefix:
|
|
259
|
-
args.extend(('--log-prefix', log_prefix))
|
|
260
|
-
|
|
261
|
-
if to_destination:
|
|
262
|
-
args.extend(('--to-destination', to_destination))
|
|
263
|
-
|
|
264
|
-
if to_source:
|
|
265
|
-
args.extend(('--to-source', to_source))
|
|
266
|
-
|
|
267
|
-
if to_ports:
|
|
268
|
-
args.extend(('--to-ports', to_ports))
|
|
269
|
-
|
|
270
|
-
# Build the final iptables command
|
|
271
|
-
yield ' '.join(args)
|
pyinfra/modules/lxd.py
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
'''
|
|
2
|
-
The LXD modules manage LXD containers
|
|
3
|
-
'''
|
|
4
|
-
|
|
5
|
-
from pyinfra.api import operation
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def get_container_named(name, containers):
|
|
9
|
-
for container in containers:
|
|
10
|
-
if container['name'] == name:
|
|
11
|
-
return container
|
|
12
|
-
else:
|
|
13
|
-
return None
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@operation
|
|
17
|
-
def container(
|
|
18
|
-
state, host, name,
|
|
19
|
-
present=True, image='ubuntu:16.04',
|
|
20
|
-
):
|
|
21
|
-
'''
|
|
22
|
-
Add/remove LXD containers.
|
|
23
|
-
|
|
24
|
-
Note: does not check if an existing container is based on the specified
|
|
25
|
-
image.
|
|
26
|
-
|
|
27
|
-
+ name: name of the container
|
|
28
|
-
+ image: image to base the container on
|
|
29
|
-
+ present: whether the container should be present or absent
|
|
30
|
-
'''
|
|
31
|
-
|
|
32
|
-
container = get_container_named(name, host.fact.lxd_containers)
|
|
33
|
-
|
|
34
|
-
# Container exists and we don't want it
|
|
35
|
-
if container and not present:
|
|
36
|
-
if container['status'] == 'Running':
|
|
37
|
-
yield 'lxc stop {0}'.format(name)
|
|
38
|
-
|
|
39
|
-
# Command to remove the container:
|
|
40
|
-
yield 'lxc delete {0}'.format(name)
|
|
41
|
-
|
|
42
|
-
# Container doesn't exist and we want it
|
|
43
|
-
if not container and present:
|
|
44
|
-
# Command to create the container:
|
|
45
|
-
yield 'lxc launch {image} {name}'.format(name=name, image=image)
|
pyinfra/modules/mysql.py
DELETED
|
@@ -1,347 +0,0 @@
|
|
|
1
|
-
'''
|
|
2
|
-
Manage MySQL databases, users and privileges.
|
|
3
|
-
|
|
4
|
-
Requires the ``mysql`` CLI executable on the target host(s).
|
|
5
|
-
|
|
6
|
-
All operations in this module take four optional global arguments:
|
|
7
|
-
+ ``mysql_user``: the username to connect to mysql to
|
|
8
|
-
+ ``mysql_password``: the password for the connecting user
|
|
9
|
-
+ ``mysql_host``: the hostname of the server to connect to
|
|
10
|
-
+ ``mysql_port``: the port of the server to connect to
|
|
11
|
-
'''
|
|
12
|
-
|
|
13
|
-
from pyinfra.api import operation, OperationError
|
|
14
|
-
from pyinfra.facts.mysql import make_execute_mysql_command, make_mysql_command
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@operation
|
|
18
|
-
def sql(
|
|
19
|
-
state, host, sql,
|
|
20
|
-
database=None,
|
|
21
|
-
# Details for speaking to MySQL via `mysql` CLI
|
|
22
|
-
mysql_user=None, mysql_password=None,
|
|
23
|
-
mysql_host=None, mysql_port=None,
|
|
24
|
-
):
|
|
25
|
-
'''
|
|
26
|
-
Execute arbitrary SQL against MySQL.
|
|
27
|
-
|
|
28
|
-
+ sql: SQL command(s) to execute
|
|
29
|
-
+ database: optional database to open the connection with
|
|
30
|
-
+ mysql_*: global module arguments, see above
|
|
31
|
-
'''
|
|
32
|
-
|
|
33
|
-
yield make_execute_mysql_command(
|
|
34
|
-
sql,
|
|
35
|
-
database=database,
|
|
36
|
-
user=mysql_user,
|
|
37
|
-
password=mysql_password,
|
|
38
|
-
host=mysql_host,
|
|
39
|
-
port=mysql_port,
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@operation
|
|
44
|
-
def user(
|
|
45
|
-
state, host, name,
|
|
46
|
-
# Desired user settings
|
|
47
|
-
present=True,
|
|
48
|
-
user_hostname='localhost', password=None, privileges=None,
|
|
49
|
-
# Details for speaking to MySQL via `mysql` CLI via `mysql` CLI
|
|
50
|
-
mysql_user=None, mysql_password=None,
|
|
51
|
-
mysql_host=None, mysql_port=None,
|
|
52
|
-
):
|
|
53
|
-
'''
|
|
54
|
-
Add/remove/update MySQL users.
|
|
55
|
-
|
|
56
|
-
+ name: the name of the user
|
|
57
|
-
+ present: whether the user should exist or not
|
|
58
|
-
+ user_hostname: the hostname of the user
|
|
59
|
-
+ password: the password of the user (if created)
|
|
60
|
-
+ privileges: the global privileges for this user
|
|
61
|
-
+ mysql_*: global module arguments, see above
|
|
62
|
-
|
|
63
|
-
Hostname:
|
|
64
|
-
this + ``name`` makes the username - so changing this will create a new
|
|
65
|
-
user, rather than update users with the same ``name``.
|
|
66
|
-
|
|
67
|
-
Password:
|
|
68
|
-
will only be applied if the user does not exist - ie pyinfra cannot
|
|
69
|
-
detect if the current password doesn't match the one provided, so won't
|
|
70
|
-
attempt to change it.
|
|
71
|
-
'''
|
|
72
|
-
|
|
73
|
-
current_users = host.fact.mysql_users(
|
|
74
|
-
mysql_user, mysql_password, mysql_host, mysql_port,
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
user_host = '{0}@{1}'.format(name, user_hostname)
|
|
78
|
-
is_present = user_host in current_users
|
|
79
|
-
|
|
80
|
-
# User not wanted?
|
|
81
|
-
if not present:
|
|
82
|
-
if is_present:
|
|
83
|
-
yield make_execute_mysql_command(
|
|
84
|
-
'DROP USER "{0}"@"{1}"'.format(name, user_hostname),
|
|
85
|
-
user=mysql_user,
|
|
86
|
-
password=mysql_password,
|
|
87
|
-
host=mysql_host,
|
|
88
|
-
port=mysql_port,
|
|
89
|
-
)
|
|
90
|
-
return
|
|
91
|
-
|
|
92
|
-
# If we want the user and they don't exist
|
|
93
|
-
if present and not is_present:
|
|
94
|
-
sql_bits = ['CREATE USER "{0}"@"{1}"'.format(name, user_hostname)]
|
|
95
|
-
if password:
|
|
96
|
-
sql_bits.append('IDENTIFIED BY "{0}"'.format(password))
|
|
97
|
-
|
|
98
|
-
yield make_execute_mysql_command(
|
|
99
|
-
' '.join(sql_bits),
|
|
100
|
-
user=mysql_user,
|
|
101
|
-
password=mysql_password,
|
|
102
|
-
host=mysql_host,
|
|
103
|
-
port=mysql_port,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
# If we're here either the user exists or we just created them; either way
|
|
107
|
-
# now we can check any privileges are set.
|
|
108
|
-
if privileges:
|
|
109
|
-
yield _privileges(
|
|
110
|
-
state, host, name, privileges,
|
|
111
|
-
user_hostname=user_hostname,
|
|
112
|
-
mysql_user=mysql_user, mysql_password=mysql_password,
|
|
113
|
-
mysql_host=mysql_host, mysql_port=mysql_port,
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
@operation
|
|
118
|
-
def database(
|
|
119
|
-
state, host, name,
|
|
120
|
-
# Desired database settings
|
|
121
|
-
present=True,
|
|
122
|
-
collate=None, charset=None,
|
|
123
|
-
user=None, user_hostname='localhost', user_privileges='ALL',
|
|
124
|
-
# Details for speaking to MySQL via `mysql` CLI
|
|
125
|
-
mysql_user=None, mysql_password=None,
|
|
126
|
-
mysql_host=None, mysql_port=None,
|
|
127
|
-
):
|
|
128
|
-
'''
|
|
129
|
-
Add/remove MySQL databases.
|
|
130
|
-
|
|
131
|
-
+ name: the name of the database
|
|
132
|
-
+ present: whether the database should exist or not
|
|
133
|
-
+ collate: the collate to use when creating the database
|
|
134
|
-
+ charset: the charset to use when creating the database
|
|
135
|
-
+ user: MySQL user to grant privileges on this database to
|
|
136
|
-
+ user_hostname: the hostname of the MySQL user to grant
|
|
137
|
-
+ user_privileges: privileges to grant to any specified user
|
|
138
|
-
+ mysql_*: global module arguments, see above
|
|
139
|
-
|
|
140
|
-
Collate/charset:
|
|
141
|
-
these will only be applied if the database does not exist - ie pyinfra
|
|
142
|
-
will not attempt to alter the existing databases collate/character sets.
|
|
143
|
-
'''
|
|
144
|
-
|
|
145
|
-
current_databases = host.fact.mysql_databases(
|
|
146
|
-
mysql_user, mysql_password,
|
|
147
|
-
mysql_host, mysql_port,
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
is_present = name in current_databases
|
|
151
|
-
|
|
152
|
-
if not present:
|
|
153
|
-
if is_present:
|
|
154
|
-
yield make_execute_mysql_command(
|
|
155
|
-
'DROP DATABASE {0}'.format(name),
|
|
156
|
-
user=mysql_user,
|
|
157
|
-
password=mysql_password,
|
|
158
|
-
host=mysql_host,
|
|
159
|
-
port=mysql_port,
|
|
160
|
-
)
|
|
161
|
-
return
|
|
162
|
-
|
|
163
|
-
# We want the database but it doesn't exist
|
|
164
|
-
if present and not is_present:
|
|
165
|
-
sql_bits = ['CREATE DATABASE {0}'.format(name)]
|
|
166
|
-
|
|
167
|
-
if collate:
|
|
168
|
-
sql_bits.append('COLLATE {0}'.format(collate))
|
|
169
|
-
|
|
170
|
-
if charset:
|
|
171
|
-
sql_bits.append('CHARSET {0}'.format(charset))
|
|
172
|
-
|
|
173
|
-
yield make_execute_mysql_command(
|
|
174
|
-
' '.join(sql_bits),
|
|
175
|
-
user=mysql_user,
|
|
176
|
-
password=mysql_password,
|
|
177
|
-
host=mysql_host,
|
|
178
|
-
port=mysql_port,
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
# Ensure any user privileges for this database
|
|
182
|
-
if user and user_privileges:
|
|
183
|
-
yield privileges(
|
|
184
|
-
state, host, user,
|
|
185
|
-
user_hostname=user_hostname,
|
|
186
|
-
privileges=user_privileges,
|
|
187
|
-
database=name,
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
@operation
|
|
192
|
-
def privileges(
|
|
193
|
-
state, host,
|
|
194
|
-
user, privileges,
|
|
195
|
-
user_hostname='localhost',
|
|
196
|
-
database='*', table='*',
|
|
197
|
-
present=True,
|
|
198
|
-
flush=True,
|
|
199
|
-
# Details for speaking to MySQL via `mysql` CLI
|
|
200
|
-
mysql_user=None, mysql_password=None,
|
|
201
|
-
mysql_host=None, mysql_port=None,
|
|
202
|
-
):
|
|
203
|
-
'''
|
|
204
|
-
Add/remove MySQL privileges for a user, either global, database or table specific.
|
|
205
|
-
|
|
206
|
-
+ user: name of the user to manage privileges for
|
|
207
|
-
+ privileges: list of privileges the user should have
|
|
208
|
-
+ user_hostname: the hostname of the user
|
|
209
|
-
+ database: name of the database to grant privileges to (defaults to all)
|
|
210
|
-
+ table: name of the table to grant privileges to (defaults to all)
|
|
211
|
-
+ present: whether these privileges should exist (False to ``REVOKE)
|
|
212
|
-
+ flush: whether to flush (and update) the privileges table after any changes
|
|
213
|
-
+ mysql_*: global module arguments, see above
|
|
214
|
-
'''
|
|
215
|
-
|
|
216
|
-
# Ensure we have a list
|
|
217
|
-
if isinstance(privileges, str):
|
|
218
|
-
privileges = [privileges]
|
|
219
|
-
|
|
220
|
-
if database != '*':
|
|
221
|
-
database = '`{0}`'.format(database)
|
|
222
|
-
|
|
223
|
-
if table != '*':
|
|
224
|
-
table = '`{0}`'.format(table)
|
|
225
|
-
|
|
226
|
-
# We can't set privileges on *.tablename as MySQL won't allow it
|
|
227
|
-
if database == '*':
|
|
228
|
-
raise OperationError((
|
|
229
|
-
'Cannot apply MySQL privileges on {0}.{1}, no database provided'
|
|
230
|
-
).format(database, table))
|
|
231
|
-
|
|
232
|
-
database_table = '{0}.{1}'.format(database, table)
|
|
233
|
-
user_grants = host.fact.mysql_user_grants(
|
|
234
|
-
user, user_hostname,
|
|
235
|
-
mysql_user, mysql_password,
|
|
236
|
-
mysql_host, mysql_port,
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
has_privileges = False
|
|
240
|
-
|
|
241
|
-
if database_table in user_grants:
|
|
242
|
-
existing_privileges = [
|
|
243
|
-
'ALL' if privilege == 'ALL PRIVILEGES' else privilege
|
|
244
|
-
for privilege in user_grants[database_table]['privileges']
|
|
245
|
-
]
|
|
246
|
-
|
|
247
|
-
has_privileges = (
|
|
248
|
-
database_table in user_grants
|
|
249
|
-
and all(
|
|
250
|
-
privilege in existing_privileges
|
|
251
|
-
for privilege in privileges
|
|
252
|
-
)
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
target = action = None
|
|
256
|
-
|
|
257
|
-
# No privilege and we want it
|
|
258
|
-
if not has_privileges and present:
|
|
259
|
-
action = 'GRANT'
|
|
260
|
-
target = 'TO'
|
|
261
|
-
|
|
262
|
-
# Permission we don't want
|
|
263
|
-
elif has_privileges and not present:
|
|
264
|
-
action = 'REVOKE'
|
|
265
|
-
target = 'FROM'
|
|
266
|
-
|
|
267
|
-
if target and action:
|
|
268
|
-
command = (
|
|
269
|
-
'{action} {privileges} '
|
|
270
|
-
'ON {database}.{table} '
|
|
271
|
-
'{target} "{user}"@"{user_hostname}"'
|
|
272
|
-
).format(
|
|
273
|
-
privileges=', '.join(privileges),
|
|
274
|
-
action=action, target=target,
|
|
275
|
-
database=database, table=table,
|
|
276
|
-
user=user, user_hostname=user_hostname,
|
|
277
|
-
).replace('`', r'\`')
|
|
278
|
-
|
|
279
|
-
yield make_execute_mysql_command(
|
|
280
|
-
command,
|
|
281
|
-
user=mysql_user,
|
|
282
|
-
password=mysql_password,
|
|
283
|
-
host=mysql_host,
|
|
284
|
-
port=mysql_port,
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
if flush:
|
|
288
|
-
yield make_execute_mysql_command(
|
|
289
|
-
'FLUSH PRIVILEGES',
|
|
290
|
-
user=mysql_user,
|
|
291
|
-
password=mysql_password,
|
|
292
|
-
host=mysql_host,
|
|
293
|
-
port=mysql_port,
|
|
294
|
-
)
|
|
295
|
-
|
|
296
|
-
_privileges = privileges # noqa: E305 (for use where kwarg is the same)
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
@operation
|
|
300
|
-
def dump(
|
|
301
|
-
state, host,
|
|
302
|
-
remote_filename, database=None,
|
|
303
|
-
# Details for speaking to MySQL via `mysql` CLI
|
|
304
|
-
mysql_user=None, mysql_password=None,
|
|
305
|
-
mysql_host=None, mysql_port=None,
|
|
306
|
-
):
|
|
307
|
-
'''
|
|
308
|
-
Dump a MySQL database into a ``.sql`` file. Requires ``mysqldump``.
|
|
309
|
-
|
|
310
|
-
+ database: name of the database to dump
|
|
311
|
-
+ remote_filename: name of the file to dump the SQL to
|
|
312
|
-
+ mysql_*: global module arguments, see above
|
|
313
|
-
'''
|
|
314
|
-
|
|
315
|
-
yield '{0} > {1}'.format(make_mysql_command(
|
|
316
|
-
executable='mysqldump',
|
|
317
|
-
database=database,
|
|
318
|
-
user=mysql_user,
|
|
319
|
-
password=mysql_password,
|
|
320
|
-
host=mysql_host,
|
|
321
|
-
port=mysql_port,
|
|
322
|
-
), remote_filename)
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
@operation
|
|
326
|
-
def load(
|
|
327
|
-
state, host,
|
|
328
|
-
remote_filename, database=None,
|
|
329
|
-
# Details for speaking to MySQL via `mysql` CLI
|
|
330
|
-
mysql_user=None, mysql_password=None,
|
|
331
|
-
mysql_host=None, mysql_port=None,
|
|
332
|
-
):
|
|
333
|
-
'''
|
|
334
|
-
Load ``.sql`` file into a database.
|
|
335
|
-
|
|
336
|
-
+ database: name of the database to import into
|
|
337
|
-
+ remote_filename: the filename to read from
|
|
338
|
-
+ mysql_*: global module arguments, see above
|
|
339
|
-
'''
|
|
340
|
-
|
|
341
|
-
yield '{0} < {1}'.format(make_mysql_command(
|
|
342
|
-
database=database,
|
|
343
|
-
user=mysql_user,
|
|
344
|
-
password=mysql_password,
|
|
345
|
-
host=mysql_host,
|
|
346
|
-
port=mysql_port,
|
|
347
|
-
), remote_filename)
|
pyinfra/modules/npm.py
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
from pyinfra.api import operation
|
|
2
|
-
|
|
3
|
-
from .util.packaging import ensure_packages
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@operation
|
|
7
|
-
def packages(state, host, packages=None, present=True, latest=False, directory=None):
|
|
8
|
-
'''
|
|
9
|
-
Install/remove/update npm packages.
|
|
10
|
-
|
|
11
|
-
+ packages: list of packages to ensure
|
|
12
|
-
+ present: whether the packages should be present
|
|
13
|
-
+ latest: whether to upgrade packages without a specified version
|
|
14
|
-
+ directory: directory to manage packages for, defaults to global
|
|
15
|
-
|
|
16
|
-
Versions:
|
|
17
|
-
Package versions can be pinned like npm: ``<pkg>@<version>``.
|
|
18
|
-
'''
|
|
19
|
-
|
|
20
|
-
current_packages = host.fact.npm_packages(directory)
|
|
21
|
-
|
|
22
|
-
install_command = (
|
|
23
|
-
'npm install -g'
|
|
24
|
-
if directory is None
|
|
25
|
-
else 'cd {0} && npm install'.format(directory)
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
uninstall_command = (
|
|
29
|
-
'npm uninstall -g'
|
|
30
|
-
if directory is None
|
|
31
|
-
else 'cd {0} && npm uninstall'.format(directory)
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
upgrade_command = (
|
|
35
|
-
'npm update -g'
|
|
36
|
-
if directory is None
|
|
37
|
-
else 'cd {0} && npm update'.format(directory)
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
yield ensure_packages(
|
|
41
|
-
packages, current_packages, present,
|
|
42
|
-
install_command=install_command,
|
|
43
|
-
uninstall_command=uninstall_command,
|
|
44
|
-
upgrade_command=upgrade_command,
|
|
45
|
-
version_join='@',
|
|
46
|
-
latest=latest,
|
|
47
|
-
)
|