synapse 2.224.0__py311-none-any.whl → 2.225.0__py311-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.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/axon.py +10 -5
- synapse/lib/cell.py +1 -1
- synapse/lib/const.py +4 -0
- synapse/lib/multislabseqn.py +36 -1
- synapse/lib/nexus.py +67 -8
- synapse/lib/queue.py +4 -1
- synapse/lib/rstorm.py +2 -2
- synapse/lib/schemas.py +11 -1
- synapse/lib/slabseqn.py +28 -0
- synapse/lib/storm.py +5 -1
- synapse/lib/stormhttp.py +7 -1
- synapse/lib/version.py +2 -2
- synapse/models/inet.py +4 -0
- synapse/models/media.py +4 -0
- synapse/models/risk.py +3 -0
- synapse/tests/test_cortex.py +2 -2
- synapse/tests/test_lib_agenda.py +1 -1
- synapse/tests/test_lib_cell.py +1 -1
- synapse/tests/test_lib_certdir.py +1 -1
- synapse/tests/test_lib_httpapi.py +1 -1
- synapse/tests/test_lib_layer.py +1 -1
- synapse/tests/test_lib_multislabseqn.py +22 -0
- synapse/tests/test_lib_nexus.py +42 -1
- synapse/tests/test_lib_slabseqn.py +30 -1
- synapse/tests/test_lib_storm.py +59 -1
- synapse/tests/test_lib_stormhttp.py +16 -0
- synapse/tests/test_lib_stormlib_oauth.py +1 -1
- synapse/tests/test_lib_stormsvc.py +1 -1
- synapse/tests/test_lib_trigger.py +1 -1
- synapse/tests/test_model_inet.py +6 -0
- synapse/tests/test_model_media.py +4 -1
- synapse/tests/test_model_risk.py +2 -0
- synapse/tests/{test_tools_axon2axon.py → test_tools_axon_copy.py} +4 -4
- synapse/tests/{test_tools_pullfile.py → test_tools_axon_get.py} +4 -4
- synapse/tests/{test_tools_pushfile.py → test_tools_axon_put.py} +7 -7
- synapse/tests/{test_tools_csvtool.py → test_tools_cortex_csv.py} +12 -3
- synapse/tests/{test_tools_feed.py → test_tools_cortex_feed.py} +2 -2
- synapse/tests/{test_tools_apikey.py → test_tools_service_apikey.py} +1 -4
- synapse/tests/{test_tools_backup.py → test_tools_service_backup.py} +5 -5
- synapse/tests/{test_tools_demote.py → test_tools_service_demote.py} +1 -1
- synapse/tests/{test_tools_healthcheck.py → test_tools_service_healthcheck.py} +1 -1
- synapse/tests/{test_tools_livebackup.py → test_tools_service_livebackup.py} +1 -1
- synapse/tests/{test_tools_modrole.py → test_tools_service_modrole.py} +1 -1
- synapse/tests/{test_tools_moduser.py → test_tools_service_moduser.py} +1 -1
- synapse/tests/{test_tools_promote.py → test_tools_service_promote.py} +1 -1
- synapse/tests/{test_tools_reload.py → test_tools_service_reload.py} +1 -1
- synapse/tests/{test_tools_shutdown.py → test_tools_service_shutdown.py} +1 -1
- synapse/tests/{test_tools_snapshot.py → test_tools_service_snapshot.py} +1 -1
- synapse/tests/{test_tools_storm.py → test_tools_storm_cli.py} +1 -1
- synapse/tests/{test_tools_pkgs_gendocs.py → test_tools_storm_pkg_doc.py} +12 -3
- synapse/tests/{test_tools_genpkg.py → test_tools_storm_pkg_gen.py} +1 -1
- synapse/tests/{test_tools_autodoc.py → test_tools_utils_autodoc.py} +1 -1
- synapse/tests/test_tools_utils_changelog.py +454 -0
- synapse/tests/{test_tools_easycert.py → test_tools_utils_easycert.py} +48 -46
- synapse/tests/{test_tools_guid.py → test_tools_utils_guid.py} +3 -3
- synapse/tests/{test_tools_json2mpk.py → test_tools_utils_json2mpk.py} +3 -3
- synapse/tests/{test_tools_rstorm.py → test_tools_utils_rstorm.py} +6 -1
- synapse/tests/utils.py +3 -1
- synapse/tools/apikey.py +4 -83
- synapse/tools/autodoc.py +3 -1031
- synapse/tools/axon/copy.py +44 -0
- synapse/tools/axon/get.py +64 -0
- synapse/tools/axon/put.py +122 -0
- synapse/tools/axon2axon.py +3 -36
- synapse/tools/backup.py +6 -176
- synapse/tools/changelog.py +3 -1098
- synapse/tools/cortex/csv.py +236 -0
- synapse/tools/cortex/feed.py +151 -0
- synapse/tools/csvtool.py +3 -227
- synapse/tools/demote.py +4 -40
- synapse/tools/docker/validate.py +3 -3
- synapse/tools/easycert.py +4 -129
- synapse/tools/feed.py +3 -140
- synapse/tools/genpkg.py +3 -307
- synapse/tools/guid.py +7 -6
- synapse/tools/healthcheck.py +3 -101
- synapse/tools/json2mpk.py +6 -38
- synapse/tools/livebackup.py +4 -27
- synapse/tools/modrole.py +3 -108
- synapse/tools/moduser.py +3 -179
- synapse/tools/pkgs/gendocs.py +3 -164
- synapse/tools/promote.py +4 -41
- synapse/tools/pullfile.py +3 -56
- synapse/tools/pushfile.py +3 -114
- synapse/tools/reload.py +4 -61
- synapse/tools/rstorm.py +3 -26
- synapse/tools/service/__init__.py +0 -0
- synapse/tools/service/apikey.py +90 -0
- synapse/tools/service/backup.py +181 -0
- synapse/tools/service/demote.py +47 -0
- synapse/tools/service/healthcheck.py +109 -0
- synapse/tools/service/livebackup.py +34 -0
- synapse/tools/service/modrole.py +116 -0
- synapse/tools/service/moduser.py +184 -0
- synapse/tools/service/promote.py +48 -0
- synapse/tools/service/reload.py +68 -0
- synapse/tools/service/shutdown.py +51 -0
- synapse/tools/service/snapshot.py +64 -0
- synapse/tools/shutdown.py +5 -45
- synapse/tools/snapshot.py +4 -57
- synapse/tools/storm/__init__.py +0 -0
- synapse/tools/storm/__main__.py +5 -0
- synapse/tools/{storm.py → storm/_cli.py} +0 -3
- synapse/tools/storm/pkg/__init__.py +0 -0
- synapse/tools/{pkgs/pandoc_filter.py → storm/pkg/_pandoc_filter.py} +1 -1
- synapse/tools/storm/pkg/doc.py +176 -0
- synapse/tools/storm/pkg/gen.py +315 -0
- synapse/tools/utils/__init__.py +0 -0
- synapse/tools/utils/autodoc.py +1040 -0
- synapse/tools/utils/changelog.py +1124 -0
- synapse/tools/utils/easycert.py +136 -0
- synapse/tools/utils/guid.py +11 -0
- synapse/tools/utils/json2mpk.py +46 -0
- synapse/tools/utils/rstorm.py +35 -0
- {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/METADATA +1 -1
- {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/RECORD +120 -91
- synapse/tests/test_tools_changelog.py +0 -196
- /synapse/tests/{test_tools_axon.py → test_tools_axon_dump_load.py} +0 -0
- {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/WHEEL +0 -0
- {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/top_level.txt +0 -0
synapse/tools/docker/validate.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import re
|
|
2
|
-
import sys
|
|
3
2
|
import base64
|
|
4
3
|
import pprint
|
|
5
4
|
import argparse
|
|
@@ -9,6 +8,7 @@ import synapse.exc as s_exc
|
|
|
9
8
|
import synapse.data as s_data
|
|
10
9
|
import synapse.common as s_common
|
|
11
10
|
|
|
11
|
+
import synapse.lib.cmd as s_cmd
|
|
12
12
|
import synapse.lib.json as s_json
|
|
13
13
|
import synapse.lib.output as s_outp
|
|
14
14
|
import synapse.lib.certdir as s_certdir
|
|
@@ -108,7 +108,7 @@ def checkCosignSignature(outp, pubk_byts, image_to_verify):
|
|
|
108
108
|
outp.printf(pprint.pformat(blob))
|
|
109
109
|
return True
|
|
110
110
|
|
|
111
|
-
def main(argv, outp=s_outp.stdout): # pragma: no cover
|
|
111
|
+
async def main(argv, outp=s_outp.stdout): # pragma: no cover
|
|
112
112
|
pars = getArgParser()
|
|
113
113
|
opts = pars.parse_args(argv)
|
|
114
114
|
|
|
@@ -151,4 +151,4 @@ def getArgParser(): # pragma: no cover
|
|
|
151
151
|
return pars
|
|
152
152
|
|
|
153
153
|
if __name__ == '__main__': # pragma: no cover
|
|
154
|
-
|
|
154
|
+
s_cmd.exitmain(main)
|
synapse/tools/easycert.py
CHANGED
|
@@ -1,136 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import synapse.common as s_common
|
|
2
2
|
|
|
3
|
-
import synapse.exc as s_exc
|
|
4
3
|
import synapse.lib.cmd as s_cmd
|
|
5
|
-
import synapse.lib.output as s_output
|
|
6
|
-
import synapse.lib.certdir as s_certdir
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
Command line tool to generate simple x509 certs
|
|
10
|
-
'''
|
|
5
|
+
from synapse.tools.utils.easycert import main
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
pars = argparse.ArgumentParser(prog='easycert', description=descr)
|
|
15
|
-
pars.add_argument('--certdir', default='~/.syn/certs', help='Directory for certs/keys')
|
|
16
|
-
pars.add_argument('--importfile', choices=('cas', 'hosts', 'users'), help='import certs and/or keys into local certdir')
|
|
17
|
-
|
|
18
|
-
pars.add_argument('--ca', default=False, action='store_true', help='mark the certificate as a CA/CRL signer')
|
|
19
|
-
pars.add_argument('--crl', default=False, action='store_true', help='Generate a new CRL for the given CA name.')
|
|
20
|
-
pars.add_argument('--p12', default=False, action='store_true', help='mark the certificate as a p12 archive')
|
|
21
|
-
pars.add_argument('--code', default=False, action='store_true', help='mark the certificate for use in code signing.')
|
|
22
|
-
pars.add_argument('--server', default=False, action='store_true', help='mark the certificate as a server')
|
|
23
|
-
pars.add_argument('--server-sans', help='server cert subject alternate names')
|
|
24
|
-
|
|
25
|
-
pars.add_argument('--csr', default=False, action='store_true', help='generate a cert signing request')
|
|
26
|
-
pars.add_argument('--sign-csr', default=False, action='store_true', help='sign a cert signing request')
|
|
27
|
-
pars.add_argument('--signas', help='sign the new cert with the given cert name')
|
|
28
|
-
pars.add_argument('--revokeas', help='Revoke a cert as the given CA and add it to the CSR.')
|
|
29
|
-
|
|
30
|
-
pars.add_argument('name', help='common name for the certificate (or filename for CSR signing)')
|
|
31
|
-
|
|
32
|
-
opts = pars.parse_args(argv)
|
|
33
|
-
|
|
34
|
-
cdir = s_certdir.CertDir(path=opts.certdir)
|
|
35
|
-
|
|
36
|
-
try:
|
|
37
|
-
|
|
38
|
-
if opts.crl:
|
|
39
|
-
|
|
40
|
-
crl = cdir.genCaCrl(opts.name)
|
|
41
|
-
crl._save()
|
|
42
|
-
|
|
43
|
-
outp.printf(f'CRL saved: {crl.path}')
|
|
44
|
-
|
|
45
|
-
return 0
|
|
46
|
-
|
|
47
|
-
if opts.revokeas:
|
|
48
|
-
|
|
49
|
-
if opts.code:
|
|
50
|
-
cert = cdir.getCodeCert(opts.name)
|
|
51
|
-
|
|
52
|
-
elif opts.server:
|
|
53
|
-
cert = cdir.getHostCert(opts.name)
|
|
54
|
-
|
|
55
|
-
elif opts.ca:
|
|
56
|
-
cert = cdir.getCaCert(opts.name)
|
|
57
|
-
|
|
58
|
-
else:
|
|
59
|
-
cert = cdir.getUserCert(opts.name)
|
|
60
|
-
|
|
61
|
-
if cert is None:
|
|
62
|
-
outp.printf(f'Certificate not found: {opts.name}')
|
|
63
|
-
return 1
|
|
64
|
-
|
|
65
|
-
crl = cdir.genCaCrl(opts.revokeas)
|
|
66
|
-
try:
|
|
67
|
-
crl.revoke(cert)
|
|
68
|
-
except s_exc.SynErr as e:
|
|
69
|
-
outp.printf(f'Failed to revoke certificate: {e.get("mesg")}')
|
|
70
|
-
return 1
|
|
71
|
-
|
|
72
|
-
outp.printf(f'Certificate revoked: {opts.name}')
|
|
73
|
-
outp.printf(f'CRL updated: {opts.revokeas}')
|
|
74
|
-
|
|
75
|
-
return 0
|
|
76
|
-
|
|
77
|
-
if opts.importfile:
|
|
78
|
-
cdir.importFile(opts.name, opts.importfile, outp=outp)
|
|
79
|
-
return 0
|
|
80
|
-
|
|
81
|
-
if opts.p12:
|
|
82
|
-
|
|
83
|
-
cdir.genClientCert(opts.name, outp=outp)
|
|
84
|
-
return 0
|
|
85
|
-
|
|
86
|
-
if opts.sign_csr:
|
|
87
|
-
|
|
88
|
-
if opts.signas is None:
|
|
89
|
-
outp.printf('--sign-csr requires --signas')
|
|
90
|
-
return 1
|
|
91
|
-
|
|
92
|
-
xcsr = cdir._loadCsrPath(opts.name)
|
|
93
|
-
if xcsr is None:
|
|
94
|
-
outp.printf('csr not found: %s' % (opts.name,))
|
|
95
|
-
return 1
|
|
96
|
-
|
|
97
|
-
if opts.server:
|
|
98
|
-
cdir.signHostCsr(xcsr, opts.signas, outp=outp)
|
|
99
|
-
return 0
|
|
100
|
-
|
|
101
|
-
cdir.signUserCsr(xcsr, opts.signas, outp=outp)
|
|
102
|
-
return 0
|
|
103
|
-
|
|
104
|
-
if opts.csr:
|
|
105
|
-
|
|
106
|
-
if opts.ca:
|
|
107
|
-
raise NotImplementedError('CSR for CA cert not supported (yet)')
|
|
108
|
-
|
|
109
|
-
if opts.server:
|
|
110
|
-
cdir.genHostCsr(opts.name, outp=outp)
|
|
111
|
-
return 0
|
|
112
|
-
|
|
113
|
-
cdir.genUserCsr(opts.name, outp=outp)
|
|
114
|
-
return 0
|
|
115
|
-
|
|
116
|
-
if opts.ca:
|
|
117
|
-
cdir.genCaCert(opts.name, signas=opts.signas, outp=outp)
|
|
118
|
-
return 0
|
|
119
|
-
|
|
120
|
-
if opts.server:
|
|
121
|
-
cdir.genHostCert(opts.name, signas=opts.signas, outp=outp, sans=opts.server_sans)
|
|
122
|
-
return 0
|
|
123
|
-
|
|
124
|
-
if opts.code:
|
|
125
|
-
cdir.genCodeCert(opts.name, signas=opts.signas, outp=outp)
|
|
126
|
-
return 0
|
|
127
|
-
|
|
128
|
-
cdir.genUserCert(opts.name, signas=opts.signas, outp=outp)
|
|
129
|
-
return 0
|
|
130
|
-
|
|
131
|
-
except s_exc.DupFileName as e:
|
|
132
|
-
outp.printf('file exists: %s' % (e.errinfo.get('path'),))
|
|
133
|
-
return 1
|
|
7
|
+
s_common.deprecated('synapse.tools.easycert is deprecated. Please use synapse.tools.utils.easycert instead.',
|
|
8
|
+
curv='v2.225.0')
|
|
134
9
|
|
|
135
10
|
if __name__ == '__main__': # pragma: no cover
|
|
136
11
|
s_cmd.exitmain(main)
|
synapse/tools/feed.py
CHANGED
|
@@ -1,148 +1,11 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import time
|
|
3
|
-
import logging
|
|
4
|
-
|
|
5
|
-
import synapse.exc as s_exc
|
|
6
1
|
import synapse.common as s_common
|
|
7
|
-
import synapse.cortex as s_cortex
|
|
8
|
-
import synapse.telepath as s_telepath
|
|
9
2
|
|
|
10
3
|
import synapse.lib.cmd as s_cmd
|
|
11
|
-
import synapse.lib.cmdr as s_cmdr
|
|
12
|
-
import synapse.lib.json as s_json
|
|
13
|
-
import synapse.lib.output as s_output
|
|
14
|
-
import synapse.lib.msgpack as s_msgpack
|
|
15
|
-
import synapse.lib.version as s_version
|
|
16
|
-
import synapse.lib.encoding as s_encoding
|
|
17
|
-
|
|
18
|
-
logger = logging.getLogger(__name__)
|
|
19
|
-
|
|
20
|
-
reqver = '>=0.2.0,<3.0.0'
|
|
21
|
-
|
|
22
|
-
def getItems(*paths):
|
|
23
|
-
items = []
|
|
24
|
-
for path in paths:
|
|
25
|
-
if path.endswith('.json'):
|
|
26
|
-
item = s_json.jsload(path)
|
|
27
|
-
if not isinstance(item, list):
|
|
28
|
-
item = [item]
|
|
29
|
-
items.append((path, item))
|
|
30
|
-
elif path.endswith('.jsonl'):
|
|
31
|
-
with s_common.genfile(path) as fd:
|
|
32
|
-
item = list(s_encoding.iterdata(fd, False, format='jsonl'))
|
|
33
|
-
items.append((path, item))
|
|
34
|
-
elif path.endswith(('.yaml', '.yml')):
|
|
35
|
-
item = s_common.yamlload(path)
|
|
36
|
-
if not isinstance(item, list):
|
|
37
|
-
item = [item]
|
|
38
|
-
items.append((path, item))
|
|
39
|
-
elif path.endswith('.mpk') or path.endswith('.nodes'):
|
|
40
|
-
genr = s_msgpack.iterfile(path)
|
|
41
|
-
items.append((path, genr))
|
|
42
|
-
else: # pragma: no cover
|
|
43
|
-
logger.warning('Unsupported file path: [%s]', path)
|
|
44
|
-
return items
|
|
45
|
-
|
|
46
|
-
async def addFeedData(core, outp, feedformat, debug=False, *paths, chunksize=1000, offset=0, viewiden=None):
|
|
47
|
-
|
|
48
|
-
items = getItems(*paths)
|
|
49
|
-
for path, item in items:
|
|
50
|
-
|
|
51
|
-
bname = os.path.basename(path)
|
|
52
|
-
|
|
53
|
-
tick = time.time()
|
|
54
|
-
outp.printf(f'Adding items from [{path}]')
|
|
55
|
-
|
|
56
|
-
foff = 0
|
|
57
|
-
for chunk in s_common.chunks(item, chunksize):
|
|
58
|
-
|
|
59
|
-
clen = len(chunk)
|
|
60
|
-
if offset and foff + clen < offset:
|
|
61
|
-
# We have not yet encountered a chunk which
|
|
62
|
-
# will include the offset size.
|
|
63
|
-
foff += clen
|
|
64
|
-
continue
|
|
65
|
-
|
|
66
|
-
await core.addFeedData(feedformat, chunk, viewiden=viewiden)
|
|
67
|
-
|
|
68
|
-
foff += clen
|
|
69
|
-
outp.printf(f'Added [{clen}] items from [{bname}] - offset [{foff}]')
|
|
70
|
-
|
|
71
|
-
tock = time.time()
|
|
72
|
-
|
|
73
|
-
outp.printf(f'Done consuming from [{bname}]')
|
|
74
|
-
outp.printf(f'Took [{tock - tick}] seconds.')
|
|
75
|
-
|
|
76
|
-
if debug:
|
|
77
|
-
await s_cmdr.runItemCmdr(core, outp, True)
|
|
78
|
-
|
|
79
|
-
async def main(argv, outp=s_output.stdout):
|
|
80
|
-
|
|
81
|
-
pars = getArgParser(outp)
|
|
82
|
-
opts = pars.parse_args(argv)
|
|
83
|
-
|
|
84
|
-
if opts.offset:
|
|
85
|
-
if len(opts.files) > 1:
|
|
86
|
-
outp.printf('Cannot start from a arbitrary offset for more than 1 file.')
|
|
87
|
-
return 1
|
|
88
|
-
|
|
89
|
-
outp.printf(f'Starting from offset [{opts.offset}] - it may take a while'
|
|
90
|
-
f' to get to that location in the input file.')
|
|
91
|
-
|
|
92
|
-
if opts.test:
|
|
93
|
-
async with s_cortex.getTempCortex(mods=opts.modules) as prox:
|
|
94
|
-
await addFeedData(prox, outp, opts.format, opts.debug,
|
|
95
|
-
chunksize=opts.chunksize,
|
|
96
|
-
offset=opts.offset,
|
|
97
|
-
*opts.files)
|
|
98
|
-
|
|
99
|
-
elif opts.cortex:
|
|
100
|
-
async with s_telepath.withTeleEnv():
|
|
101
|
-
async with await s_telepath.openurl(opts.cortex) as core:
|
|
102
|
-
try:
|
|
103
|
-
s_version.reqVersion(core._getSynVers(), reqver)
|
|
104
|
-
except s_exc.BadVersion as e:
|
|
105
|
-
valu = s_version.fmtVersion(*e.get('valu'))
|
|
106
|
-
outp.printf(f'Cortex version {valu} is outside of the feed tool supported range ({reqver}).')
|
|
107
|
-
outp.printf(f'Please use a version of Synapse which supports {valu}; '
|
|
108
|
-
f'current version is {s_version.verstring}.')
|
|
109
|
-
return 1
|
|
110
|
-
await addFeedData(core, outp, opts.format, opts.debug,
|
|
111
|
-
chunksize=opts.chunksize,
|
|
112
|
-
offset=opts.offset, viewiden=opts.view,
|
|
113
|
-
*opts.files)
|
|
114
|
-
|
|
115
|
-
else: # pragma: no cover
|
|
116
|
-
outp.printf('No valid options provided [%s]', opts)
|
|
117
|
-
return 1
|
|
118
|
-
|
|
119
|
-
return 0
|
|
120
|
-
|
|
121
|
-
def getArgParser(outp):
|
|
122
|
-
desc = 'Command line tool for ingesting data into a cortex'
|
|
123
|
-
pars = s_cmd.Parser(prog='synapse.tools.feed', outp=outp, description=desc)
|
|
124
|
-
|
|
125
|
-
muxp = pars.add_mutually_exclusive_group(required=True)
|
|
126
|
-
muxp.add_argument('--cortex', '-c', type=str,
|
|
127
|
-
help='Cortex to connect and add nodes too.')
|
|
128
|
-
muxp.add_argument('--test', '-t', default=False, action='store_true',
|
|
129
|
-
help='Perform a local ingest against a temporary cortex.')
|
|
130
4
|
|
|
131
|
-
|
|
132
|
-
help='Drop to interactive prompt to inspect cortex after loading data.')
|
|
133
|
-
pars.add_argument('--format', '-f', type=str, action='store', default='syn.nodes',
|
|
134
|
-
help='Feed format to use for the ingested data.')
|
|
135
|
-
pars.add_argument('--modules', '-m', type=str, action='append', default=[],
|
|
136
|
-
help='Additional modules to load locally with a test Cortex.')
|
|
137
|
-
pars.add_argument('--chunksize', type=int, action='store', default=1000,
|
|
138
|
-
help='Default chunksize for iterating over items.')
|
|
139
|
-
pars.add_argument('--offset', type=int, action='store', default=0,
|
|
140
|
-
help='Item offset to start consuming data from.')
|
|
141
|
-
pars.add_argument('--view', type=str, action='store', default=None,
|
|
142
|
-
help='The View to ingest the data into.')
|
|
143
|
-
pars.add_argument('files', nargs='*', help='json/yaml/msgpack feed files')
|
|
5
|
+
from synapse.tools.cortex.feed import logger, main
|
|
144
6
|
|
|
145
|
-
|
|
7
|
+
s_common.deprecated('synapse.tools.feed is deprecated. Please use synapse.tools.cortex.feed instead.',
|
|
8
|
+
curv='v2.225.0')
|
|
146
9
|
|
|
147
10
|
if __name__ == '__main__': # pragma: no cover
|
|
148
11
|
s_common.setlogging(logger, 'DEBUG')
|
synapse/tools/genpkg.py
CHANGED
|
@@ -1,315 +1,11 @@
|
|
|
1
|
-
import io
|
|
2
|
-
import os
|
|
3
|
-
import base64
|
|
4
|
-
import logging
|
|
5
|
-
|
|
6
|
-
import regex
|
|
7
|
-
|
|
8
|
-
import synapse.exc as s_exc
|
|
9
1
|
import synapse.common as s_common
|
|
10
|
-
import synapse.telepath as s_telepath
|
|
11
2
|
|
|
12
3
|
import synapse.lib.cmd as s_cmd
|
|
13
|
-
import synapse.lib.json as s_json
|
|
14
|
-
import synapse.lib.output as s_output
|
|
15
|
-
import synapse.lib.certdir as s_certdir
|
|
16
|
-
import synapse.lib.dyndeps as s_dyndeps
|
|
17
|
-
import synapse.lib.schemas as s_schemas
|
|
18
|
-
import synapse.lib.version as s_version
|
|
19
|
-
|
|
20
|
-
logger = logging.getLogger(__name__)
|
|
21
|
-
|
|
22
|
-
wflownamere = regex.compile(r'^([\w-]+)\.yaml$')
|
|
23
|
-
|
|
24
|
-
def getStormStr(fn):
|
|
25
|
-
if not os.path.isfile(fn):
|
|
26
|
-
raise s_exc.NoSuchFile(mesg='Storm file {} not found'.format(fn), path=fn)
|
|
27
|
-
|
|
28
|
-
with open(fn, 'rb') as f:
|
|
29
|
-
return f.read().decode()
|
|
30
|
-
|
|
31
|
-
def loadOpticFiles(pkgdef, path):
|
|
32
|
-
|
|
33
|
-
pkgfiles = pkgdef['optic']['files']
|
|
34
|
-
|
|
35
|
-
abspath = s_common.genpath(path)
|
|
36
|
-
for root, dirs, files, in os.walk(path):
|
|
37
|
-
|
|
38
|
-
for name in files:
|
|
39
|
-
|
|
40
|
-
if name.startswith('.'): # pragma: no cover
|
|
41
|
-
continue
|
|
42
|
-
|
|
43
|
-
fullname = s_common.genpath(root, name)
|
|
44
|
-
if not os.path.isfile(fullname): # pragma: no cover
|
|
45
|
-
continue
|
|
46
|
-
|
|
47
|
-
pkgfname = fullname[len(abspath) + 1:]
|
|
48
|
-
|
|
49
|
-
with open(fullname, 'rb') as fd:
|
|
50
|
-
pkgfiles[pkgfname] = {
|
|
51
|
-
'file': base64.b64encode(fd.read()).decode(),
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
def loadOpticWorkflows(pkgdef, path):
|
|
55
|
-
|
|
56
|
-
wdefs = pkgdef['optic']['workflows']
|
|
57
|
-
|
|
58
|
-
for root, dirs, files in os.walk(path):
|
|
59
|
-
|
|
60
|
-
for name in files:
|
|
61
|
-
|
|
62
|
-
match = wflownamere.match(name)
|
|
63
|
-
|
|
64
|
-
if match is None:
|
|
65
|
-
logger.warning('Skipping workflow "%s" that does not match pattern "%s"' % (name, wflownamere.pattern))
|
|
66
|
-
continue
|
|
67
|
-
|
|
68
|
-
wname = match.groups()[0]
|
|
69
|
-
|
|
70
|
-
fullname = s_common.genpath(root, name)
|
|
71
|
-
if not os.path.isfile(fullname): # pragma: no cover
|
|
72
|
-
continue
|
|
73
|
-
|
|
74
|
-
wdefs[wname] = s_common.yamlload(fullname)
|
|
75
|
-
|
|
76
|
-
def tryLoadPkgProto(fp, opticdir=None, readonly=False):
|
|
77
|
-
'''
|
|
78
|
-
Try to get a Storm Package prototype from disk with or without inline documentation.
|
|
79
|
-
|
|
80
|
-
Args:
|
|
81
|
-
fp (str): Path to the package .yaml file on disk.
|
|
82
|
-
opticdir (str): Path to optional Optic module code to add to the Storm Package.
|
|
83
|
-
readonly (bool): If set, open files in read-only mode. If files are missing, that will raise a NoSuchFile
|
|
84
|
-
exception.
|
|
85
|
-
|
|
86
|
-
Returns:
|
|
87
|
-
dict: A Storm package definition.
|
|
88
|
-
'''
|
|
89
|
-
try:
|
|
90
|
-
return loadPkgProto(fp, opticdir=opticdir, readonly=readonly)
|
|
91
|
-
except s_exc.NoSuchFile:
|
|
92
|
-
return loadPkgProto(fp, opticdir=opticdir, no_docs=True, readonly=readonly)
|
|
93
|
-
|
|
94
|
-
def loadPkgProto(path, opticdir=None, no_docs=False, readonly=False):
|
|
95
|
-
'''
|
|
96
|
-
Get a Storm Package definition from disk.
|
|
97
|
-
|
|
98
|
-
Args:
|
|
99
|
-
path (str): Path to the package .yaml file on disk.
|
|
100
|
-
opticdir (str): Path to optional Optic module code to add to the Storm Package.
|
|
101
|
-
no_docs (bool): If true, omit inline documentation content if it is not present on disk.
|
|
102
|
-
readonly (bool): If set, open files in read-only mode. If files are missing, that will raise a NoSuchFile
|
|
103
|
-
exception.
|
|
104
|
-
|
|
105
|
-
Returns:
|
|
106
|
-
dict: A Storm package definition.
|
|
107
|
-
'''
|
|
108
|
-
|
|
109
|
-
full = s_common.genpath(path)
|
|
110
|
-
pkgdef = s_common.yamlload(full)
|
|
111
|
-
if pkgdef is None:
|
|
112
|
-
raise s_exc.NoSuchFile(mesg=f'File {full} does not exist or is empty.', path=full)
|
|
113
|
-
|
|
114
|
-
version = pkgdef.get('version')
|
|
115
|
-
if isinstance(version, (tuple, list)):
|
|
116
|
-
pkgdef['version'] = '%d.%d.%d' % tuple(version)
|
|
117
|
-
|
|
118
|
-
protodir = os.path.dirname(full)
|
|
119
|
-
pkgname = pkgdef.get('name')
|
|
120
|
-
|
|
121
|
-
genopts = pkgdef.pop('genopts', {})
|
|
122
|
-
|
|
123
|
-
# Stamp build info into the pkgdef if it doesn't already exist
|
|
124
|
-
pkgdef.setdefault('build', {})
|
|
125
|
-
pkgdef['build'].setdefault('time', s_common.now())
|
|
126
|
-
pkgdef['build'].setdefault('synapse:version', s_version.verstring)
|
|
127
|
-
pkgdef['build'].setdefault('synapse:commit', s_version.commit)
|
|
128
|
-
|
|
129
|
-
logodef = pkgdef.get('logo')
|
|
130
|
-
if logodef is not None:
|
|
131
|
-
|
|
132
|
-
path = logodef.pop('path', None)
|
|
133
|
-
|
|
134
|
-
if path is not None:
|
|
135
|
-
with s_common.reqfile(protodir, path) as fd:
|
|
136
|
-
logodef['file'] = base64.b64encode(fd.read()).decode()
|
|
137
|
-
|
|
138
|
-
if logodef.get('mime') is None:
|
|
139
|
-
mesg = 'Mime type must be specified for logo file.'
|
|
140
|
-
raise s_exc.BadPkgDef(mesg=mesg)
|
|
141
|
-
|
|
142
|
-
if logodef.get('file') is None:
|
|
143
|
-
mesg = 'Logo def must contain path or file.'
|
|
144
|
-
raise s_exc.BadPkgDef(mesg=mesg)
|
|
145
|
-
|
|
146
|
-
for docdef in pkgdef.get('docs', ()):
|
|
147
|
-
|
|
148
|
-
if docdef.get('title') is None:
|
|
149
|
-
mesg = 'Each entry in docs must have a title.'
|
|
150
|
-
raise s_exc.BadPkgDef(mesg=mesg)
|
|
151
|
-
|
|
152
|
-
if no_docs:
|
|
153
|
-
docdef['content'] = ''
|
|
154
|
-
continue
|
|
155
|
-
|
|
156
|
-
path = docdef.pop('path', None)
|
|
157
|
-
if path is not None:
|
|
158
|
-
with s_common.reqfile(protodir, path) as fd:
|
|
159
|
-
docdef['content'] = fd.read().decode()
|
|
160
|
-
|
|
161
|
-
if docdef.get('content') is None:
|
|
162
|
-
mesg = 'Docs entry has no path or content.'
|
|
163
|
-
raise s_exc.BadPkgDef(mesg=mesg)
|
|
164
|
-
|
|
165
|
-
for mod in pkgdef.get('modules', ()):
|
|
166
|
-
|
|
167
|
-
name = mod.get('name')
|
|
168
|
-
|
|
169
|
-
basename = name
|
|
170
|
-
if genopts.get('dotstorm', False):
|
|
171
|
-
basename = f'{basename}.storm'
|
|
172
|
-
|
|
173
|
-
mod_path = s_common.genpath(protodir, 'storm', 'modules', basename)
|
|
174
|
-
if readonly:
|
|
175
|
-
mod['storm'] = getStormStr(mod_path)
|
|
176
|
-
else:
|
|
177
|
-
with s_common.genfile(mod_path) as fd:
|
|
178
|
-
mod['storm'] = fd.read().decode()
|
|
179
|
-
|
|
180
|
-
for extmod in pkgdef.get('external_modules', ()):
|
|
181
|
-
fpth = extmod.get('file_path')
|
|
182
|
-
if fpth is not None:
|
|
183
|
-
extmod['storm'] = getStormStr(fpth)
|
|
184
|
-
else:
|
|
185
|
-
path = extmod.get('package_path')
|
|
186
|
-
extpkg = s_dyndeps.tryDynMod(extmod.get('package'))
|
|
187
|
-
extmod['storm'] = extpkg.getAssetStr(path)
|
|
188
|
-
|
|
189
|
-
extname = extmod.get('name')
|
|
190
|
-
extmod['name'] = f'{pkgname}.{extname}'
|
|
191
|
-
|
|
192
|
-
pkgdef.setdefault('modules', [])
|
|
193
|
-
pkgdef['modules'].append(extmod)
|
|
194
|
-
|
|
195
|
-
pkgdef.pop('external_modules', None)
|
|
196
|
-
|
|
197
|
-
for cmd in pkgdef.get('commands', ()):
|
|
198
|
-
name = cmd.get('name')
|
|
199
|
-
|
|
200
|
-
basename = name
|
|
201
|
-
if genopts.get('dotstorm'):
|
|
202
|
-
basename = f'{basename}.storm'
|
|
203
|
-
|
|
204
|
-
cmd_path = s_common.genpath(protodir, 'storm', 'commands', basename)
|
|
205
|
-
if readonly:
|
|
206
|
-
cmd['storm'] = getStormStr(cmd_path)
|
|
207
|
-
else:
|
|
208
|
-
with s_common.genfile(cmd_path) as fd:
|
|
209
|
-
cmd['storm'] = fd.read().decode()
|
|
210
|
-
|
|
211
|
-
for gdef in pkgdef.get('graphs', ()):
|
|
212
|
-
gdef['iden'] = s_common.guid((pkgname, gdef.get('name')))
|
|
213
|
-
gdef['scope'] = 'power-up'
|
|
214
|
-
gdef['power-up'] = pkgname
|
|
215
|
-
|
|
216
|
-
inits = pkgdef.get('inits')
|
|
217
|
-
if inits is not None:
|
|
218
|
-
lastver = None
|
|
219
|
-
for initdef in inits.get('versions'):
|
|
220
|
-
curver = initdef.get('version')
|
|
221
|
-
if lastver is not None and not curver > lastver:
|
|
222
|
-
raise s_exc.BadPkgDef(mesg='Init versions must be monotonically increasing.', version=curver)
|
|
223
|
-
lastver = curver
|
|
224
|
-
|
|
225
|
-
wflowdir = s_common.genpath(protodir, 'workflows')
|
|
226
|
-
if os.path.isdir(wflowdir):
|
|
227
|
-
pkgdef.setdefault('optic', {})
|
|
228
|
-
pkgdef['optic'].setdefault('workflows', {})
|
|
229
|
-
loadOpticWorkflows(pkgdef, wflowdir)
|
|
230
|
-
|
|
231
|
-
if opticdir is None:
|
|
232
|
-
opticdir = s_common.genpath(protodir, 'optic')
|
|
233
|
-
|
|
234
|
-
if os.path.isdir(opticdir):
|
|
235
|
-
pkgdef.setdefault('optic', {})
|
|
236
|
-
pkgdef['optic'].setdefault('files', {})
|
|
237
|
-
loadOpticFiles(pkgdef, opticdir)
|
|
238
|
-
|
|
239
|
-
s_schemas.reqValidPkgdef(pkgdef)
|
|
240
|
-
|
|
241
|
-
# Ensure the package is json safe and tuplify it.
|
|
242
|
-
s_json.reqjsonsafe(pkgdef, strict=True)
|
|
243
|
-
pkgdef = s_common.tuplify(pkgdef)
|
|
244
|
-
return pkgdef
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
desc = 'A tool for generating/pushing storm packages from YAML prototypes.'
|
|
248
|
-
|
|
249
|
-
async def main(argv, outp=s_output.stdout):
|
|
250
|
-
|
|
251
|
-
pars = s_cmd.Parser(prog='synapse.tools.genpkg', outp=outp, description=desc)
|
|
252
|
-
pars.add_argument('--push', metavar='<url>', help='A telepath URL of a Cortex or PkgRepo.')
|
|
253
|
-
pars.add_argument('--push-verify', default=False, action='store_true',
|
|
254
|
-
help='Tell the Cortex to verify the package signature.')
|
|
255
|
-
pars.add_argument('--save', metavar='<path>', help='Save the completed package JSON to a file.')
|
|
256
|
-
pars.add_argument('--optic', metavar='<path>', help='Load Optic module files from a directory.')
|
|
257
|
-
pars.add_argument('--signas', metavar='<name>', help='Specify a code signing identity to use from ~/.syn/certs/code.')
|
|
258
|
-
pars.add_argument('--certdir', metavar='<dir>', default='~/.syn/certs',
|
|
259
|
-
help='Specify an alternate certdir to ~/.syn/certs.')
|
|
260
|
-
pars.add_argument('--no-build', action='store_true',
|
|
261
|
-
help='Treat pkgfile argument as an already-built package')
|
|
262
|
-
pars.add_argument('--no-docs', default=False, action='store_true',
|
|
263
|
-
help='Do not require docs to be present and replace any doc content with empty strings.')
|
|
264
|
-
pars.add_argument('pkgfile', metavar='<pkgfile>',
|
|
265
|
-
help='Path to a storm package prototype .yaml file, or a completed package .json/.yaml file.')
|
|
266
|
-
|
|
267
|
-
opts = pars.parse_args(argv)
|
|
268
|
-
|
|
269
|
-
if opts.no_build:
|
|
270
|
-
pkgdef = s_common.yamlload(opts.pkgfile)
|
|
271
|
-
if not pkgdef:
|
|
272
|
-
outp.printf(f'Unable to load pkgdef from [{opts.pkgfile}]')
|
|
273
|
-
return 1
|
|
274
|
-
if opts.save:
|
|
275
|
-
outp.printf(f'File {opts.pkgfile} is treated as already built (--no-build); incompatible with --save.')
|
|
276
|
-
return 1
|
|
277
|
-
else:
|
|
278
|
-
pkgdef = loadPkgProto(opts.pkgfile, opticdir=opts.optic, no_docs=opts.no_docs)
|
|
279
|
-
|
|
280
|
-
if opts.signas is not None:
|
|
281
|
-
|
|
282
|
-
s_certdir.addCertPath(opts.certdir)
|
|
283
|
-
certdir = s_certdir.getCertDir()
|
|
284
|
-
|
|
285
|
-
pkey = certdir.getCodeKey(opts.signas)
|
|
286
|
-
with io.open(certdir.getCodeCertPath(opts.signas)) as fd:
|
|
287
|
-
cert = fd.read()
|
|
288
|
-
|
|
289
|
-
sign = s_common.ehex(pkey.signitem(pkgdef))
|
|
290
|
-
|
|
291
|
-
pkgdef['codesign'] = {
|
|
292
|
-
'cert': cert,
|
|
293
|
-
'sign': sign,
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
s_schemas.reqValidPkgdef(pkgdef)
|
|
297
|
-
|
|
298
|
-
if not opts.save and not opts.push:
|
|
299
|
-
outp.printf('Neither --push nor --save provided. Nothing to do.')
|
|
300
|
-
return 1
|
|
301
|
-
|
|
302
|
-
if opts.save:
|
|
303
|
-
s_json.jssave(pkgdef, opts.save)
|
|
304
|
-
|
|
305
|
-
if opts.push:
|
|
306
|
-
|
|
307
|
-
async with s_telepath.withTeleEnv():
|
|
308
4
|
|
|
309
|
-
|
|
310
|
-
await core.addStormPkg(pkgdef, verify=opts.push_verify)
|
|
5
|
+
from synapse.tools.storm.pkg.gen import main, tryLoadPkgProto, loadPkgProto
|
|
311
6
|
|
|
312
|
-
|
|
7
|
+
s_common.deprecated('synapse.tools.genpkg is deprecated. Please use synapse.tools.storm.pkg.gen instead.',
|
|
8
|
+
curv='v2.225.0')
|
|
313
9
|
|
|
314
10
|
if __name__ == '__main__': # pragma: no cover
|
|
315
11
|
s_cmd.exitmain(main)
|
synapse/tools/guid.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
|
|
3
1
|
import synapse.common as s_common
|
|
4
|
-
import synapse.lib.output as s_output
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import synapse.lib.cmd as s_cmd
|
|
4
|
+
|
|
5
|
+
from synapse.tools.utils.guid import main
|
|
6
|
+
|
|
7
|
+
s_common.deprecated('synapse.tools.guid is deprecated. Please use synapse.tools.utils.guid instead.',
|
|
8
|
+
curv='v2.225.0')
|
|
8
9
|
|
|
9
10
|
if __name__ == '__main__': # pragma: no cover
|
|
10
|
-
|
|
11
|
+
s_cmd.exitmain(main)
|