synapse 2.177.0__py311-none-any.whl → 2.179.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/cortex.py +170 -31
- synapse/datamodel.py +47 -1
- synapse/exc.py +1 -0
- synapse/lib/aha.py +362 -88
- synapse/lib/ast.py +26 -22
- synapse/lib/base.py +39 -12
- synapse/lib/cell.py +315 -119
- synapse/lib/config.py +15 -11
- synapse/lib/coro.py +27 -0
- synapse/lib/drive.py +551 -0
- synapse/lib/layer.py +0 -5
- synapse/lib/link.py +1 -1
- synapse/lib/lmdbslab.py +3 -3
- synapse/lib/nexus.py +24 -12
- synapse/lib/schemas.py +39 -0
- synapse/lib/snap.py +17 -7
- synapse/lib/storm.py +3 -1
- synapse/lib/stormhttp.py +1 -0
- synapse/lib/stormlib/imap.py +6 -2
- synapse/lib/stormlib/modelext.py +29 -3
- synapse/lib/stormlib/smtp.py +12 -2
- synapse/lib/stormlib/stix.py +40 -17
- synapse/lib/stormlib/vault.py +2 -2
- synapse/lib/stormtypes.py +1 -1
- synapse/lib/types.py +9 -0
- synapse/lib/version.py +2 -2
- synapse/lookup/pe.py +303 -38
- synapse/models/dns.py +24 -1
- synapse/models/geospace.py +4 -1
- synapse/models/infotech.py +26 -1
- synapse/telepath.py +32 -17
- synapse/tests/files/aha/certs/cas/synapse.crt +28 -0
- synapse/tests/files/aha/certs/cas/synapse.key +51 -0
- synapse/tests/files/aha/certs/hosts/00.aha.loop.vertex.link.crt +30 -0
- synapse/tests/files/aha/certs/hosts/00.aha.loop.vertex.link.key +51 -0
- synapse/tests/files/aha/certs/users/root@synapse.crt +29 -0
- synapse/tests/files/aha/certs/users/root@synapse.key +51 -0
- synapse/tests/files/rstorm/testsvc.py +1 -1
- synapse/tests/test_axon.py +1 -1
- synapse/tests/test_cortex.py +67 -60
- synapse/tests/test_lib_agenda.py +3 -3
- synapse/tests/test_lib_aha.py +353 -490
- synapse/tests/test_lib_base.py +20 -0
- synapse/tests/test_lib_cell.py +273 -22
- synapse/tests/test_lib_config.py +4 -3
- synapse/tests/test_lib_coro.py +12 -0
- synapse/tests/test_lib_nexus.py +8 -0
- synapse/tests/test_lib_stormhttp.py +40 -0
- synapse/tests/test_lib_stormlib_aha.py +35 -35
- synapse/tests/test_lib_stormlib_cell.py +4 -15
- synapse/tests/test_lib_stormlib_imap.py +14 -3
- synapse/tests/test_lib_stormlib_modelext.py +55 -3
- synapse/tests/test_lib_stormlib_smtp.py +51 -0
- synapse/tests/test_lib_stormlib_stix.py +15 -0
- synapse/tests/test_lib_stormlib_vault.py +11 -1
- synapse/tests/test_lib_stormtypes.py +5 -0
- synapse/tests/test_lib_types.py +9 -0
- synapse/tests/test_model_dns.py +8 -0
- synapse/tests/test_model_geospace.py +3 -1
- synapse/tests/test_model_infotech.py +47 -0
- synapse/tests/test_model_syn.py +11 -0
- synapse/tests/test_tools_aha.py +78 -101
- synapse/tests/test_utils_stormcov.py +1 -1
- synapse/tests/utils.py +86 -120
- synapse/tools/aha/clone.py +50 -0
- synapse/tools/aha/enroll.py +2 -1
- synapse/tools/backup.py +2 -2
- synapse/tools/changelog.py +31 -1
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/METADATA +48 -48
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/RECORD +73 -65
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/WHEEL +1 -1
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/LICENSE +0 -0
- {synapse-2.177.0.dist-info → synapse-2.179.0.dist-info}/top_level.txt +0 -0
synapse/lib/ast.py
CHANGED
|
@@ -1953,7 +1953,7 @@ class PivotOut(PivotOper):
|
|
|
1953
1953
|
typename = prop.type.opts.get('type')
|
|
1954
1954
|
if runt.model.forms.get(typename) is not None:
|
|
1955
1955
|
for item in valu:
|
|
1956
|
-
async for pivo in runt.snap.nodesByPropValu(typename, '=', item):
|
|
1956
|
+
async for pivo in runt.snap.nodesByPropValu(typename, '=', item, norm=False):
|
|
1957
1957
|
yield pivo, path.fork(pivo)
|
|
1958
1958
|
|
|
1959
1959
|
form = runt.model.forms.get(prop.type.name)
|
|
@@ -2090,11 +2090,13 @@ class PivotIn(PivotOper):
|
|
|
2090
2090
|
name, valu = node.ndef
|
|
2091
2091
|
|
|
2092
2092
|
for prop in runt.model.getPropsByType(name):
|
|
2093
|
-
|
|
2093
|
+
norm = node.form.typehash is not prop.typehash
|
|
2094
|
+
async for pivo in runt.snap.nodesByPropValu(prop.full, '=', valu, norm=norm):
|
|
2094
2095
|
yield pivo, path.fork(pivo)
|
|
2095
2096
|
|
|
2096
2097
|
for prop in runt.model.getArrayPropsByType(name):
|
|
2097
|
-
|
|
2098
|
+
norm = node.form.typehash is not prop.arraytypehash
|
|
2099
|
+
async for pivo in runt.snap.nodesByPropArray(prop.full, '=', valu, norm=norm):
|
|
2098
2100
|
yield pivo, path.fork(pivo)
|
|
2099
2101
|
|
|
2100
2102
|
async for refsbuid in runt.snap.getNdefRefs(node.buid):
|
|
@@ -2141,7 +2143,7 @@ class PivotInFrom(PivotOper):
|
|
|
2141
2143
|
if self.isjoin:
|
|
2142
2144
|
yield node, path
|
|
2143
2145
|
|
|
2144
|
-
async for pivo in runt.snap.nodesByPropValu(full, '=', node.ndef):
|
|
2146
|
+
async for pivo in runt.snap.nodesByPropValu(full, '=', node.ndef, norm=False):
|
|
2145
2147
|
yield pivo, path.fork(pivo)
|
|
2146
2148
|
|
|
2147
2149
|
return
|
|
@@ -2179,7 +2181,7 @@ class FormPivot(PivotOper):
|
|
|
2179
2181
|
if isinstance(prop.type, s_types.Ndef):
|
|
2180
2182
|
|
|
2181
2183
|
async def pgenr(node, strict=True):
|
|
2182
|
-
async for pivo in runt.snap.nodesByPropValu(prop.full, '=', node.ndef):
|
|
2184
|
+
async for pivo in runt.snap.nodesByPropValu(prop.full, '=', node.ndef, norm=False):
|
|
2183
2185
|
yield pivo
|
|
2184
2186
|
|
|
2185
2187
|
elif not prop.isform:
|
|
@@ -2190,13 +2192,14 @@ class FormPivot(PivotOper):
|
|
|
2190
2192
|
async def pgenr(node, strict=True):
|
|
2191
2193
|
if isarray:
|
|
2192
2194
|
if isinstance(prop.type.arraytype, s_types.Ndef):
|
|
2193
|
-
ngenr = runt.snap.nodesByPropArray(prop.full, '=', node.ndef)
|
|
2195
|
+
ngenr = runt.snap.nodesByPropArray(prop.full, '=', node.ndef, norm=False)
|
|
2194
2196
|
else:
|
|
2195
|
-
|
|
2197
|
+
norm = prop.arraytypehash is not node.form.typehash
|
|
2198
|
+
ngenr = runt.snap.nodesByPropArray(prop.full, '=', node.ndef[1], norm=norm)
|
|
2196
2199
|
else:
|
|
2197
|
-
|
|
2200
|
+
norm = prop.typehash is not node.form.typehash
|
|
2201
|
+
ngenr = runt.snap.nodesByPropValu(prop.full, '=', node.ndef[1], norm=norm)
|
|
2198
2202
|
|
|
2199
|
-
# TODO cache/bypass normalization in loop!
|
|
2200
2203
|
async for pivo in ngenr:
|
|
2201
2204
|
yield pivo
|
|
2202
2205
|
|
|
@@ -2206,7 +2209,7 @@ class FormPivot(PivotOper):
|
|
|
2206
2209
|
full = prop.name + ':n1'
|
|
2207
2210
|
|
|
2208
2211
|
async def pgenr(node, strict=True):
|
|
2209
|
-
async for pivo in runt.snap.nodesByPropValu(full, '=', node.ndef):
|
|
2212
|
+
async for pivo in runt.snap.nodesByPropValu(full, '=', node.ndef, norm=False):
|
|
2210
2213
|
yield pivo
|
|
2211
2214
|
|
|
2212
2215
|
else:
|
|
@@ -2251,7 +2254,7 @@ class FormPivot(PivotOper):
|
|
|
2251
2254
|
|
|
2252
2255
|
refsvalu = node.get(refsname)
|
|
2253
2256
|
if refsvalu is not None:
|
|
2254
|
-
async for pivo in runt.snap.nodesByPropValu(refsform, '=', refsvalu):
|
|
2257
|
+
async for pivo in runt.snap.nodesByPropValu(refsform, '=', refsvalu, norm=False):
|
|
2255
2258
|
yield pivo
|
|
2256
2259
|
|
|
2257
2260
|
for refsname, refsform in refs.get('array'):
|
|
@@ -2264,7 +2267,7 @@ class FormPivot(PivotOper):
|
|
|
2264
2267
|
refsvalu = node.get(refsname)
|
|
2265
2268
|
if refsvalu is not None:
|
|
2266
2269
|
for refselem in refsvalu:
|
|
2267
|
-
async for pivo in runt.snap.nodesByPropValu(destform.name, '=', refselem):
|
|
2270
|
+
async for pivo in runt.snap.nodesByPropValu(destform.name, '=', refselem, norm=False):
|
|
2268
2271
|
yield pivo
|
|
2269
2272
|
|
|
2270
2273
|
for refsname in refs.get('ndef'):
|
|
@@ -2300,7 +2303,7 @@ class FormPivot(PivotOper):
|
|
|
2300
2303
|
found = True
|
|
2301
2304
|
|
|
2302
2305
|
refsprop = destform.props.get(refsname)
|
|
2303
|
-
async for pivo in runt.snap.nodesByPropValu(refsprop.full, '=', node.ndef[1]):
|
|
2306
|
+
async for pivo in runt.snap.nodesByPropValu(refsprop.full, '=', node.ndef[1], norm=False):
|
|
2304
2307
|
yield pivo
|
|
2305
2308
|
|
|
2306
2309
|
# "reverse" array references...
|
|
@@ -2312,7 +2315,7 @@ class FormPivot(PivotOper):
|
|
|
2312
2315
|
found = True
|
|
2313
2316
|
|
|
2314
2317
|
destprop = destform.props.get(refsname)
|
|
2315
|
-
async for pivo in runt.snap.nodesByPropArray(destprop.full, '=', node.ndef[1]):
|
|
2318
|
+
async for pivo in runt.snap.nodesByPropArray(destprop.full, '=', node.ndef[1], norm=False):
|
|
2316
2319
|
yield pivo
|
|
2317
2320
|
|
|
2318
2321
|
# "reverse" ndef references...
|
|
@@ -2321,7 +2324,7 @@ class FormPivot(PivotOper):
|
|
|
2321
2324
|
found = True
|
|
2322
2325
|
|
|
2323
2326
|
refsprop = destform.props.get(refsname)
|
|
2324
|
-
async for pivo in runt.snap.nodesByPropValu(refsprop.full, '=', node.ndef):
|
|
2327
|
+
async for pivo in runt.snap.nodesByPropValu(refsprop.full, '=', node.ndef, norm=False):
|
|
2325
2328
|
yield pivo
|
|
2326
2329
|
|
|
2327
2330
|
for refsname in refs.get('ndefarray'):
|
|
@@ -2329,7 +2332,7 @@ class FormPivot(PivotOper):
|
|
|
2329
2332
|
found = True
|
|
2330
2333
|
|
|
2331
2334
|
refsprop = destform.props.get(refsname)
|
|
2332
|
-
async for pivo in runt.snap.nodesByPropArray(refsprop.full, '=', node.ndef):
|
|
2335
|
+
async for pivo in runt.snap.nodesByPropArray(refsprop.full, '=', node.ndef, norm=False):
|
|
2333
2336
|
yield pivo
|
|
2334
2337
|
|
|
2335
2338
|
if strict and not found:
|
|
@@ -2433,7 +2436,7 @@ class PropPivotOut(PivotOper):
|
|
|
2433
2436
|
continue
|
|
2434
2437
|
|
|
2435
2438
|
for item in valu:
|
|
2436
|
-
async for pivo in runt.snap.nodesByPropValu(fname, '=', item):
|
|
2439
|
+
async for pivo in runt.snap.nodesByPropValu(fname, '=', item, norm=False):
|
|
2437
2440
|
yield pivo, path.fork(pivo)
|
|
2438
2441
|
|
|
2439
2442
|
continue
|
|
@@ -2474,8 +2477,6 @@ class PropPivot(PivotOper):
|
|
|
2474
2477
|
|
|
2475
2478
|
async def pgenr(node, srcprop, valu, strict=True):
|
|
2476
2479
|
|
|
2477
|
-
# TODO cache/bypass normalization in loop!
|
|
2478
|
-
|
|
2479
2480
|
# pivoting from an array prop to a non-array prop needs an extra loop
|
|
2480
2481
|
if srcprop.type.isarray and not prop.type.isarray:
|
|
2481
2482
|
if isinstance(srcprop.type.arraytype, s_types.Ndef) and prop.isform:
|
|
@@ -2487,8 +2488,9 @@ class PropPivot(PivotOper):
|
|
|
2487
2488
|
yield pivo
|
|
2488
2489
|
return
|
|
2489
2490
|
|
|
2491
|
+
norm = srcprop.arraytypehash is not prop.typehash
|
|
2490
2492
|
for arrayval in valu:
|
|
2491
|
-
async for pivo in runt.snap.nodesByPropValu(prop.full, '=', arrayval):
|
|
2493
|
+
async for pivo in runt.snap.nodesByPropValu(prop.full, '=', arrayval, norm=norm):
|
|
2492
2494
|
yield pivo
|
|
2493
2495
|
|
|
2494
2496
|
return
|
|
@@ -2506,9 +2508,11 @@ class PropPivot(PivotOper):
|
|
|
2506
2508
|
return
|
|
2507
2509
|
|
|
2508
2510
|
if prop.type.isarray and not srcprop.type.isarray:
|
|
2509
|
-
|
|
2511
|
+
norm = prop.arraytypehash is not srcprop.typehash
|
|
2512
|
+
genr = runt.snap.nodesByPropArray(prop.full, '=', valu, norm=norm)
|
|
2510
2513
|
else:
|
|
2511
|
-
|
|
2514
|
+
norm = prop.typehash is not srcprop.typehash
|
|
2515
|
+
genr = runt.snap.nodesByPropValu(prop.full, '=', valu, norm=norm)
|
|
2512
2516
|
|
|
2513
2517
|
async for pivo in genr:
|
|
2514
2518
|
yield pivo
|
synapse/lib/base.py
CHANGED
|
@@ -178,7 +178,24 @@ class Base:
|
|
|
178
178
|
def onfini(self, func):
|
|
179
179
|
'''
|
|
180
180
|
Add a function/coroutine/Base to be called on fini().
|
|
181
|
+
|
|
182
|
+
The rules around how to register function/coroutine/Base to be called:
|
|
183
|
+
- Call this method with an instance of Base (this class) if holding
|
|
184
|
+
a reference to a bound method of the instance (such as a fini()
|
|
185
|
+
method) would cause the object to be leaked. This is appropriate
|
|
186
|
+
for ephemeral objects that may be constructed/destroyed multiple
|
|
187
|
+
times over the lifetime of a process.
|
|
188
|
+
|
|
189
|
+
- Call this method with an instance method if you want the object to
|
|
190
|
+
have a lifetime as long as the thing being fini'd.
|
|
181
191
|
'''
|
|
192
|
+
if self.isfini:
|
|
193
|
+
if isinstance(func, Base):
|
|
194
|
+
s_coro.create_task(func.fini())
|
|
195
|
+
else:
|
|
196
|
+
s_coro.create_task(s_coro.ornot(func))
|
|
197
|
+
return
|
|
198
|
+
|
|
182
199
|
if isinstance(func, Base):
|
|
183
200
|
self.tofini.add(func)
|
|
184
201
|
return
|
|
@@ -408,8 +425,6 @@ class Base:
|
|
|
408
425
|
for fini in self._fini_funcs:
|
|
409
426
|
try:
|
|
410
427
|
await s_coro.ornot(fini)
|
|
411
|
-
except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only
|
|
412
|
-
raise
|
|
413
428
|
except Exception:
|
|
414
429
|
logger.exception(f'{self} - fini function failed: {fini}')
|
|
415
430
|
|
|
@@ -493,9 +508,8 @@ class Base:
|
|
|
493
508
|
def taskDone(task):
|
|
494
509
|
self._active_tasks.remove(task)
|
|
495
510
|
try:
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only
|
|
511
|
+
task.result()
|
|
512
|
+
except asyncio.CancelledError:
|
|
499
513
|
pass
|
|
500
514
|
except Exception:
|
|
501
515
|
logger.exception('Task %s scheduled through Base.schedCoro raised exception', task)
|
|
@@ -579,7 +593,7 @@ class Base:
|
|
|
579
593
|
loop.add_signal_handler(signal.SIGINT, sigint)
|
|
580
594
|
loop.add_signal_handler(signal.SIGTERM, sigterm)
|
|
581
595
|
|
|
582
|
-
async def main(self):
|
|
596
|
+
async def main(self): # pragma: no cover
|
|
583
597
|
'''
|
|
584
598
|
Helper function to setup signal handlers for this base as the main object.
|
|
585
599
|
( use base.waitfini() to block )
|
|
@@ -590,7 +604,7 @@ class Base:
|
|
|
590
604
|
await self.addSignalHandlers()
|
|
591
605
|
return await self.waitfini()
|
|
592
606
|
|
|
593
|
-
def waiter(self, count, *names):
|
|
607
|
+
def waiter(self, count, *names, timeout=None):
|
|
594
608
|
'''
|
|
595
609
|
Construct and return a new Waiter for events on this base.
|
|
596
610
|
|
|
@@ -615,16 +629,17 @@ class Base:
|
|
|
615
629
|
race conditions with this mechanism ;)
|
|
616
630
|
|
|
617
631
|
'''
|
|
618
|
-
return Waiter(self, count, *names)
|
|
632
|
+
return Waiter(self, count, *names, timeout=timeout)
|
|
619
633
|
|
|
620
634
|
class Waiter:
|
|
621
635
|
'''
|
|
622
636
|
A helper to wait for a given number of events on a Base.
|
|
623
637
|
'''
|
|
624
|
-
def __init__(self, base, count, *names):
|
|
638
|
+
def __init__(self, base, count, *names, timeout=None):
|
|
625
639
|
self.base = base
|
|
626
640
|
self.names = names
|
|
627
641
|
self.count = count
|
|
642
|
+
self.timeout = timeout
|
|
628
643
|
self.event = asyncio.Event()
|
|
629
644
|
|
|
630
645
|
self.events = []
|
|
@@ -656,6 +671,9 @@ class Waiter:
|
|
|
656
671
|
doStuff(evnt)
|
|
657
672
|
|
|
658
673
|
'''
|
|
674
|
+
if timeout is None:
|
|
675
|
+
timeout = self.timeout
|
|
676
|
+
|
|
659
677
|
try:
|
|
660
678
|
|
|
661
679
|
retn = await s_coro.event_wait(self.event, timeout)
|
|
@@ -676,6 +694,18 @@ class Waiter:
|
|
|
676
694
|
self.base.unlink(self._onWaitEvent)
|
|
677
695
|
del self.event
|
|
678
696
|
|
|
697
|
+
async def __aenter__(self):
|
|
698
|
+
return self
|
|
699
|
+
|
|
700
|
+
async def __aexit__(self, exc, cls, tb):
|
|
701
|
+
if exc is None:
|
|
702
|
+
if await self.wait() is None: # pragma: no cover
|
|
703
|
+
# these lines are 100% covered by the tests but
|
|
704
|
+
# the coverage plugin cannot seem to see them...
|
|
705
|
+
events = ','.join(self.names)
|
|
706
|
+
mesg = f'timeout waiting for {self.count} event(s): {events}'
|
|
707
|
+
raise s_exc.TimeOut(mesg=mesg)
|
|
708
|
+
|
|
679
709
|
class BaseRef(Base):
|
|
680
710
|
'''
|
|
681
711
|
An object for managing multiple Base instances by name.
|
|
@@ -777,9 +807,6 @@ async def schedGenr(genr, maxsize=100):
|
|
|
777
807
|
|
|
778
808
|
await q.put((False, None))
|
|
779
809
|
|
|
780
|
-
except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only
|
|
781
|
-
raise
|
|
782
|
-
|
|
783
810
|
except Exception:
|
|
784
811
|
if not base.isfini:
|
|
785
812
|
await q.put((False, None))
|