pyinfra 0.11.dev3__py3-none-any.whl → 3.5.1__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 +18 -3
- pyinfra/api/arguments.py +406 -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 +67 -18
- pyinfra/api/facts.py +253 -202
- pyinfra/api/host.py +413 -50
- pyinfra/api/inventory.py +121 -160
- pyinfra/api/operation.py +432 -262
- pyinfra/api/operations.py +273 -260
- pyinfra/api/state.py +302 -248
- pyinfra/api/util.py +291 -368
- pyinfra/connectors/base.py +173 -0
- pyinfra/connectors/chroot.py +212 -0
- pyinfra/connectors/docker.py +381 -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 +670 -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 +410 -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 +630 -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 +746 -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 +98 -0
- pyinfra/operations/apt.py +488 -0
- pyinfra/operations/brew.py +231 -0
- pyinfra/operations/bsdinit.py +59 -0
- pyinfra/operations/cargo.py +45 -0
- pyinfra/operations/choco.py +61 -0
- pyinfra/operations/crontab.py +191 -0
- pyinfra/operations/dnf.py +210 -0
- pyinfra/operations/docker.py +446 -0
- pyinfra/operations/files.py +1939 -0
- pyinfra/operations/flatpak.py +94 -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 +47 -0
- pyinfra/operations/git.py +419 -0
- pyinfra/operations/iptables.py +311 -0
- pyinfra/operations/launchd.py +45 -0
- pyinfra/operations/lxd.py +68 -0
- pyinfra/operations/mysql.py +609 -0
- pyinfra/operations/npm.py +57 -0
- pyinfra/operations/openrc.py +63 -0
- pyinfra/operations/opkg.py +88 -0
- pyinfra/operations/pacman.py +81 -0
- pyinfra/operations/pip.py +205 -0
- pyinfra/operations/pipx.py +102 -0
- pyinfra/operations/pkg.py +70 -0
- pyinfra/operations/pkgin.py +91 -0
- pyinfra/operations/postgres.py +436 -0
- pyinfra/operations/postgresql.py +30 -0
- pyinfra/operations/puppet.py +40 -0
- pyinfra/operations/python.py +72 -0
- pyinfra/operations/runit.py +184 -0
- pyinfra/operations/selinux.py +189 -0
- pyinfra/operations/server.py +1099 -0
- pyinfra/operations/snap.py +117 -0
- pyinfra/operations/ssh.py +216 -0
- pyinfra/operations/systemd.py +149 -0
- pyinfra/operations/sysvinit.py +141 -0
- pyinfra/operations/upstart.py +68 -0
- pyinfra/operations/util/__init__.py +12 -0
- pyinfra/operations/util/docker.py +251 -0
- pyinfra/operations/util/files.py +247 -0
- pyinfra/operations/util/packaging.py +336 -0
- pyinfra/operations/util/service.py +46 -0
- pyinfra/operations/vzctl.py +137 -0
- pyinfra/operations/xbps.py +77 -0
- pyinfra/operations/yum.py +210 -0
- pyinfra/operations/zfs.py +175 -0
- pyinfra/operations/zypper.py +192 -0
- pyinfra/progress.py +44 -32
- pyinfra/py.typed +0 -0
- pyinfra/version.py +9 -1
- pyinfra-3.5.1.dist-info/METADATA +141 -0
- pyinfra-3.5.1.dist-info/RECORD +159 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.5.1.dist-info}/WHEEL +1 -2
- pyinfra-3.5.1.dist-info/entry_points.txt +12 -0
- {pyinfra-0.11.dev3.dist-info → pyinfra-3.5.1.dist-info/licenses}/LICENSE.md +1 -1
- pyinfra_cli/__init__.py +1 -0
- pyinfra_cli/cli.py +780 -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/facts/flatpak.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
from typing_extensions import override
|
|
6
|
+
|
|
7
|
+
from pyinfra.api import FactBase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FlatpakBaseFact(FactBase):
|
|
11
|
+
abstract = True
|
|
12
|
+
|
|
13
|
+
@override
|
|
14
|
+
def requires_command(self, *args, **kwargs) -> str:
|
|
15
|
+
return "flatpak"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class FlatpakPackage(FlatpakBaseFact):
|
|
19
|
+
"""
|
|
20
|
+
Returns information for an installed flatpak package
|
|
21
|
+
|
|
22
|
+
.. code:: python
|
|
23
|
+
|
|
24
|
+
{
|
|
25
|
+
"id": "org.signal.Signal",
|
|
26
|
+
"ref": "app/org.signal.Signal/x86_64/stable",
|
|
27
|
+
"version": "7.12.0"
|
|
28
|
+
}
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
default = dict
|
|
32
|
+
_regexes = {
|
|
33
|
+
"id": "^[ ]+ID:[ ]+(.*)$",
|
|
34
|
+
"ref": r"^[ ]+Ref:[ ]+(.*)$",
|
|
35
|
+
"version": r"^[ ]+Version:[ ]+([\w\d.-]+).*$",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@override
|
|
39
|
+
def command(self, package):
|
|
40
|
+
return f"flatpak info {package}"
|
|
41
|
+
|
|
42
|
+
@override
|
|
43
|
+
def process(self, output):
|
|
44
|
+
data = {}
|
|
45
|
+
for line in output:
|
|
46
|
+
for regex_name, regex in self._regexes.items():
|
|
47
|
+
matches = re.match(regex, line)
|
|
48
|
+
if matches:
|
|
49
|
+
data[regex_name] = matches.group(1)
|
|
50
|
+
|
|
51
|
+
return data
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class FlatpakPackages(FlatpakBaseFact):
|
|
55
|
+
"""
|
|
56
|
+
Returns a list of installed flatpak packages:
|
|
57
|
+
|
|
58
|
+
.. code:: python
|
|
59
|
+
|
|
60
|
+
[
|
|
61
|
+
"org.gnome.Platform",
|
|
62
|
+
"org.kde.Platform",
|
|
63
|
+
"org.kde.Sdk",
|
|
64
|
+
"org.libreoffice.LibreOffice",
|
|
65
|
+
"org.videolan.VLC"
|
|
66
|
+
]
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
default = list
|
|
70
|
+
|
|
71
|
+
@override
|
|
72
|
+
def command(self):
|
|
73
|
+
return "flatpak list --columns=application"
|
|
74
|
+
|
|
75
|
+
@override
|
|
76
|
+
def process(self, output):
|
|
77
|
+
return [flatpak for flatpak in output[1:]]
|
pyinfra/facts/freebsd.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing_extensions import Optional, override
|
|
4
|
+
|
|
5
|
+
from pyinfra.api import FactBase
|
|
6
|
+
from pyinfra.api.command import QuoteString, StringCommand, make_formatted_string_command
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ServiceScript(FactBase):
|
|
10
|
+
@override
|
|
11
|
+
def command(self, srvname: str, jail: Optional[str] = None) -> StringCommand:
|
|
12
|
+
if jail is None:
|
|
13
|
+
jail = ""
|
|
14
|
+
|
|
15
|
+
return make_formatted_string_command(
|
|
16
|
+
(
|
|
17
|
+
"for service in `service -j {0} -l`; do "
|
|
18
|
+
'if [ {1} = \\"$service\\" ]; '
|
|
19
|
+
'then echo \\"$service\\"; '
|
|
20
|
+
"fi; "
|
|
21
|
+
"done"
|
|
22
|
+
),
|
|
23
|
+
QuoteString(jail),
|
|
24
|
+
QuoteString(srvname),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ServiceStatus(FactBase):
|
|
29
|
+
@override
|
|
30
|
+
def command(self, srvname: str, jail: Optional[str] = None) -> StringCommand:
|
|
31
|
+
if jail is None:
|
|
32
|
+
jail = ""
|
|
33
|
+
|
|
34
|
+
return make_formatted_string_command(
|
|
35
|
+
("service -j {0} {1} status > /dev/null 2>&1; if [ $? -eq 0 ]; then echo running; fi"),
|
|
36
|
+
QuoteString(jail),
|
|
37
|
+
QuoteString(srvname),
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class Sysrc(FactBase):
|
|
42
|
+
@override
|
|
43
|
+
def command(self, parameter: str, jail: Optional[str] = None) -> StringCommand:
|
|
44
|
+
if jail is None:
|
|
45
|
+
command = make_formatted_string_command(
|
|
46
|
+
("sysrc -in -- {0} || true"), QuoteString(parameter)
|
|
47
|
+
)
|
|
48
|
+
else:
|
|
49
|
+
command = make_formatted_string_command(
|
|
50
|
+
("sysrc -j {0} -in -- {1} || true"), QuoteString(jail), QuoteString(parameter)
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return command
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class PkgPackage(FactBase):
|
|
57
|
+
@override
|
|
58
|
+
def command(self, package: str, jail: Optional[str] = None) -> StringCommand:
|
|
59
|
+
if jail is None:
|
|
60
|
+
command = make_formatted_string_command(
|
|
61
|
+
("pkg info -E -- {0} 2> /dev/null || true"), QuoteString(package)
|
|
62
|
+
)
|
|
63
|
+
else:
|
|
64
|
+
command = make_formatted_string_command(
|
|
65
|
+
("pkg -j {0} info -E -- {1} 2> /dev/null || true"),
|
|
66
|
+
QuoteString(jail),
|
|
67
|
+
QuoteString(package),
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
return command
|
pyinfra/facts/gem.py
CHANGED
|
@@ -1,22 +1,35 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing_extensions import override
|
|
4
|
+
|
|
1
5
|
from pyinfra.api import FactBase
|
|
2
6
|
|
|
3
7
|
from .util.packaging import parse_packages
|
|
4
8
|
|
|
5
|
-
GEM_REGEX = r
|
|
9
|
+
GEM_REGEX = r"^([a-zA-Z0-9\-\+\_]+)\s\(([0-9\.]+)\)$"
|
|
6
10
|
|
|
7
11
|
|
|
8
12
|
class GemPackages(FactBase):
|
|
9
|
-
|
|
13
|
+
"""
|
|
10
14
|
Returns a dict of installed gem packages:
|
|
11
15
|
|
|
12
16
|
.. code:: python
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
{
|
|
19
|
+
'package_name': ['version'],
|
|
20
|
+
}
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
@override
|
|
24
|
+
def command(self) -> str:
|
|
25
|
+
return "gem list --local"
|
|
26
|
+
|
|
27
|
+
@override
|
|
28
|
+
def requires_command(self) -> str:
|
|
29
|
+
return "gem"
|
|
17
30
|
|
|
18
|
-
command = 'gem list --local'
|
|
19
31
|
default = dict
|
|
20
32
|
|
|
33
|
+
@override
|
|
21
34
|
def process(self, output):
|
|
22
35
|
return parse_packages(GEM_REGEX, output)
|
pyinfra/facts/git.py
CHANGED
|
@@ -1,26 +1,71 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
from typing_extensions import override
|
|
6
|
+
|
|
1
7
|
from pyinfra.api.facts import FactBase
|
|
2
8
|
|
|
3
9
|
|
|
4
|
-
class
|
|
5
|
-
@
|
|
6
|
-
def
|
|
7
|
-
return
|
|
10
|
+
class GitFactBase(FactBase):
|
|
11
|
+
@override
|
|
12
|
+
def requires_command(self, *args, **kwargs) -> str:
|
|
13
|
+
return "git"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class GitBranch(GitFactBase):
|
|
17
|
+
@override
|
|
18
|
+
def command(self, repo) -> str:
|
|
19
|
+
return "! test -d {0} || (cd {0} && git describe --all)".format(repo)
|
|
20
|
+
|
|
21
|
+
@override
|
|
22
|
+
def process(self, output):
|
|
23
|
+
return re.sub(r"(heads|tags)/", r"", "\n".join(output))
|
|
24
|
+
|
|
8
25
|
|
|
26
|
+
class GitTag(GitFactBase):
|
|
27
|
+
@override
|
|
28
|
+
def command(self, repo) -> str:
|
|
29
|
+
return "! test -d {0} || (cd {0} && git tag)".format(repo)
|
|
9
30
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
31
|
+
@override
|
|
32
|
+
def process(self, output):
|
|
33
|
+
return output
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class GitConfig(GitFactBase):
|
|
37
|
+
default = dict
|
|
38
|
+
|
|
39
|
+
@override
|
|
40
|
+
def command(self, repo=None, system=False) -> str:
|
|
13
41
|
if repo is None:
|
|
14
|
-
|
|
42
|
+
level = "--system" if system else "--global"
|
|
43
|
+
return f"git config {level} -l || true"
|
|
15
44
|
|
|
16
|
-
return
|
|
45
|
+
return "! test -d {0} || (cd {0} && git config --local -l)".format(repo)
|
|
17
46
|
|
|
18
|
-
@
|
|
19
|
-
def process(output):
|
|
20
|
-
items = {}
|
|
47
|
+
@override
|
|
48
|
+
def process(self, output):
|
|
49
|
+
items: dict[str, list[str]] = {}
|
|
21
50
|
|
|
22
51
|
for line in output:
|
|
23
|
-
key, value = line.split(
|
|
24
|
-
items[
|
|
52
|
+
key, value = line.split("=", 1)
|
|
53
|
+
items.setdefault(key, []).append(value)
|
|
25
54
|
|
|
26
55
|
return items
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class GitTrackingBranch(GitFactBase):
|
|
59
|
+
@override
|
|
60
|
+
def command(self, repo) -> str:
|
|
61
|
+
return r"! test -d {0} || (cd {0} && git status --branch --porcelain)".format(repo)
|
|
62
|
+
|
|
63
|
+
@override
|
|
64
|
+
def process(self, output):
|
|
65
|
+
if not output:
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
m = re.search(r"\.{3}(\S+)\b", list(output)[0])
|
|
69
|
+
if m:
|
|
70
|
+
return m.group(1)
|
|
71
|
+
return None
|
pyinfra/facts/gpg.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from urllib.parse import urlparse
|
|
4
|
+
|
|
5
|
+
from typing_extensions import override
|
|
6
|
+
|
|
7
|
+
from pyinfra.api import FactBase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GpgFactBase(FactBase):
|
|
11
|
+
abstract = True
|
|
12
|
+
|
|
13
|
+
@override
|
|
14
|
+
def requires_command(self, *args, **kwargs) -> str:
|
|
15
|
+
return "gpg"
|
|
16
|
+
|
|
17
|
+
key_record_type = "pub"
|
|
18
|
+
subkey_record_type = "sub"
|
|
19
|
+
|
|
20
|
+
@override
|
|
21
|
+
def process(self, output):
|
|
22
|
+
# For details on the field values see:
|
|
23
|
+
# https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
|
|
24
|
+
keys = []
|
|
25
|
+
|
|
26
|
+
current_key = None
|
|
27
|
+
current_subkey = None
|
|
28
|
+
|
|
29
|
+
for line in output:
|
|
30
|
+
if not line:
|
|
31
|
+
continue
|
|
32
|
+
|
|
33
|
+
bits = line.split(":")
|
|
34
|
+
|
|
35
|
+
if bits[0] in (self.key_record_type, self.subkey_record_type):
|
|
36
|
+
key_details = {
|
|
37
|
+
"validity": bits[1],
|
|
38
|
+
"length": int(bits[2]),
|
|
39
|
+
"id": bits[4],
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if bits[0] == self.key_record_type:
|
|
43
|
+
key_details["subkeys"] = []
|
|
44
|
+
|
|
45
|
+
if current_key:
|
|
46
|
+
if current_subkey:
|
|
47
|
+
current_key["subkeys"].append(current_subkey)
|
|
48
|
+
|
|
49
|
+
keys.append(current_key)
|
|
50
|
+
|
|
51
|
+
current_key = key_details
|
|
52
|
+
current_subkey = None
|
|
53
|
+
elif current_key:
|
|
54
|
+
current_subkey = key_details
|
|
55
|
+
|
|
56
|
+
elif current_subkey or current_key:
|
|
57
|
+
target = current_subkey or current_key
|
|
58
|
+
assert target is not None
|
|
59
|
+
if bits[0] == "fpr":
|
|
60
|
+
target["fingerprint"] = bits[9] # fingerprint = field 10
|
|
61
|
+
elif bits[0] == "uid":
|
|
62
|
+
target["uid_hash"] = bits[7]
|
|
63
|
+
target["uid"] = bits[9]
|
|
64
|
+
|
|
65
|
+
if current_key:
|
|
66
|
+
if current_subkey:
|
|
67
|
+
current_key["subkeys"].append(current_subkey)
|
|
68
|
+
|
|
69
|
+
keys.append(current_key)
|
|
70
|
+
|
|
71
|
+
# Return as a dictionary of keyID -> details
|
|
72
|
+
keys_by_id = {}
|
|
73
|
+
for key in keys:
|
|
74
|
+
if "subkeys" in key:
|
|
75
|
+
key["subkeys"] = {subkey.pop("id"): subkey for subkey in key["subkeys"]}
|
|
76
|
+
keys_by_id[key.pop("id")] = key
|
|
77
|
+
|
|
78
|
+
return keys_by_id
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class GpgKey(GpgFactBase):
|
|
82
|
+
"""
|
|
83
|
+
Returns information on one or more GPG keys found in a file or URL.
|
|
84
|
+
|
|
85
|
+
.. code:: python
|
|
86
|
+
|
|
87
|
+
{
|
|
88
|
+
"KEY-ID": {
|
|
89
|
+
"length": 4096,
|
|
90
|
+
"uid": "Oxygem <hello@oxygem.com>"
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
@override
|
|
96
|
+
def command(self, src):
|
|
97
|
+
if urlparse(src).scheme:
|
|
98
|
+
return ("(wget -O - {0} || curl -sSLf {0}) | gpg --with-colons").format(src)
|
|
99
|
+
|
|
100
|
+
return "gpg --with-colons {0}".format(src)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class GpgKeys(GpgFactBase):
|
|
104
|
+
"""
|
|
105
|
+
Returns information on all public keys in a keychain.
|
|
106
|
+
|
|
107
|
+
.. code:: python
|
|
108
|
+
|
|
109
|
+
{
|
|
110
|
+
"KEY-ID": {
|
|
111
|
+
"length": 4096,
|
|
112
|
+
"uid": "Oxygem <hello@oxygem.com>"
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
@override
|
|
118
|
+
def command(self, keyring=None):
|
|
119
|
+
if not keyring:
|
|
120
|
+
return "gpg --list-keys --with-colons"
|
|
121
|
+
|
|
122
|
+
return ("gpg --list-keys --with-colons --keyring {0} --no-default-keyring").format(keyring)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class GpgSecretKeys(GpgFactBase):
|
|
126
|
+
"""
|
|
127
|
+
Returns information on all secret keys in a keychain.
|
|
128
|
+
|
|
129
|
+
.. code:: python
|
|
130
|
+
|
|
131
|
+
{
|
|
132
|
+
"KEY-ID": {
|
|
133
|
+
"length": 4096,
|
|
134
|
+
"fingerprint": "ABC",
|
|
135
|
+
"uid": "Oxygem <hello@oxygem.com>"
|
|
136
|
+
},
|
|
137
|
+
}
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
key_record_type = "sec"
|
|
141
|
+
subkey_record_type = "ssb"
|
|
142
|
+
|
|
143
|
+
@override
|
|
144
|
+
def command(self, keyring=None):
|
|
145
|
+
if not keyring:
|
|
146
|
+
return "gpg --list-secret-keys --with-colons"
|
|
147
|
+
|
|
148
|
+
return ("gpg --list-secret-keys --with-colons --keyring {0} --no-default-keyring").format(
|
|
149
|
+
keyring,
|
|
150
|
+
)
|