synapse 2.165.0__py311-none-any.whl → 2.167.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 +4 -10
- synapse/cmds/cortex.py +1 -6
- synapse/common.py +6 -0
- synapse/cortex.py +104 -57
- synapse/datamodel.py +32 -0
- synapse/exc.py +1 -0
- synapse/lib/agenda.py +81 -51
- synapse/lib/aha.py +2 -0
- synapse/lib/ast.py +21 -23
- synapse/lib/base.py +11 -10
- synapse/lib/cell.py +24 -24
- synapse/lib/hive.py +11 -0
- synapse/lib/httpapi.py +1 -0
- synapse/lib/nexus.py +3 -2
- synapse/lib/node.py +4 -2
- synapse/lib/schemas.py +3 -1
- synapse/lib/snap.py +50 -0
- synapse/lib/storm.py +19 -17
- synapse/lib/stormlib/aha.py +370 -17
- synapse/lib/stormlib/auth.py +11 -4
- synapse/lib/stormlib/cache.py +202 -0
- synapse/lib/stormlib/cortex.py +69 -7
- synapse/lib/stormlib/macro.py +11 -18
- synapse/lib/stormlib/spooled.py +109 -0
- synapse/lib/stormlib/stix.py +1 -1
- synapse/lib/stormtypes.py +61 -17
- synapse/lib/trigger.py +10 -12
- synapse/lib/types.py +3 -1
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +16 -3
- synapse/models/base.py +8 -0
- synapse/models/files.py +3 -0
- synapse/models/inet.py +74 -2
- synapse/models/orgs.py +52 -8
- synapse/models/person.py +30 -11
- synapse/models/risk.py +44 -3
- synapse/telepath.py +115 -32
- synapse/tests/files/stormpkg/dotstorm/dotstorm.yaml +3 -0
- synapse/tests/test_cortex.py +79 -8
- synapse/tests/test_datamodel.py +22 -0
- synapse/tests/test_lib_agenda.py +8 -1
- synapse/tests/test_lib_aha.py +19 -6
- synapse/tests/test_lib_cell.py +6 -2
- synapse/tests/test_lib_grammar.py +62 -64
- synapse/tests/test_lib_httpapi.py +1 -1
- synapse/tests/test_lib_rstorm.py +4 -4
- synapse/tests/test_lib_storm.py +98 -7
- synapse/tests/test_lib_stormlib_aha.py +196 -0
- synapse/tests/test_lib_stormlib_cache.py +272 -0
- synapse/tests/test_lib_stormlib_compression.py +12 -12
- synapse/tests/test_lib_stormlib_cortex.py +71 -0
- synapse/tests/test_lib_stormlib_macro.py +94 -0
- synapse/tests/test_lib_stormlib_spooled.py +190 -0
- synapse/tests/test_lib_stormtypes.py +71 -37
- synapse/tests/test_lib_view.py +50 -3
- synapse/tests/test_model_files.py +3 -0
- synapse/tests/test_model_inet.py +67 -0
- synapse/tests/test_model_risk.py +6 -0
- synapse/tests/test_telepath.py +30 -7
- synapse/tests/test_tools_genpkg.py +26 -0
- synapse/tests/test_tools_hiveload.py +1 -0
- synapse/tests/test_tools_hivesave.py +1 -0
- synapse/tests/test_tools_modrole.py +81 -0
- synapse/tests/test_tools_moduser.py +105 -0
- synapse/tests/utils.py +22 -3
- synapse/tools/autodoc.py +1 -1
- synapse/tools/hive/load.py +3 -0
- synapse/tools/hive/save.py +3 -0
- synapse/tools/modrole.py +59 -7
- synapse/tools/moduser.py +78 -10
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/METADATA +3 -3
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/RECORD +75 -72
- synapse/lib/provenance.py +0 -111
- synapse/tests/test_lib_provenance.py +0 -37
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/LICENSE +0 -0
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/WHEEL +0 -0
- {synapse-2.165.0.dist-info → synapse-2.167.0.dist-info}/top_level.txt +0 -0
synapse/lib/agenda.py
CHANGED
|
@@ -16,7 +16,6 @@ import synapse.common as s_common
|
|
|
16
16
|
|
|
17
17
|
import synapse.lib.base as s_base
|
|
18
18
|
import synapse.lib.coro as s_coro
|
|
19
|
-
import synapse.lib.provenance as s_provenance
|
|
20
19
|
|
|
21
20
|
# Agenda: manages running one-shot and periodic tasks in the future ("appointments")
|
|
22
21
|
|
|
@@ -259,6 +258,7 @@ class _Appt:
|
|
|
259
258
|
_synced_attrs = {
|
|
260
259
|
'doc',
|
|
261
260
|
'name',
|
|
261
|
+
'pool',
|
|
262
262
|
'created',
|
|
263
263
|
'enabled',
|
|
264
264
|
'errcount',
|
|
@@ -271,10 +271,11 @@ class _Appt:
|
|
|
271
271
|
'lastfinishtime',
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
-
def __init__(self, stor, iden, recur, indx, query, creator, recs, nexttime=None, view=None, created=None):
|
|
274
|
+
def __init__(self, stor, iden, recur, indx, query, creator, recs, nexttime=None, view=None, created=None, pool=False):
|
|
275
275
|
self.doc = ''
|
|
276
276
|
self.name = ''
|
|
277
277
|
self.stor = stor
|
|
278
|
+
self.pool = pool
|
|
278
279
|
self.iden = iden
|
|
279
280
|
self.recur = recur # does this appointment repeat
|
|
280
281
|
self.indx = indx # incremented for each appt added ever. Used for nexttime tiebreaking for stable ordering
|
|
@@ -339,6 +340,7 @@ class _Appt:
|
|
|
339
340
|
'ver': 1,
|
|
340
341
|
'doc': self.doc,
|
|
341
342
|
'name': self.name,
|
|
343
|
+
'pool': self.pool,
|
|
342
344
|
'enabled': self.enabled,
|
|
343
345
|
'recur': self.recur,
|
|
344
346
|
'iden': self.iden,
|
|
@@ -366,6 +368,7 @@ class _Appt:
|
|
|
366
368
|
appt = cls(stor, val['iden'], val['recur'], val['indx'], val['query'], val['creator'], recs, nexttime=val['nexttime'], view=val.get('view'))
|
|
367
369
|
appt.doc = val.get('doc', '')
|
|
368
370
|
appt.name = val.get('name', '')
|
|
371
|
+
appt.pool = val.get('pool', False)
|
|
369
372
|
appt.created = val.get('created', None)
|
|
370
373
|
appt.laststarttime = val['laststarttime']
|
|
371
374
|
appt.lastfinishtime = val['lastfinishtime']
|
|
@@ -562,6 +565,8 @@ class Agenda(s_base.Base):
|
|
|
562
565
|
view = cdef.get('view')
|
|
563
566
|
created = cdef.get('created')
|
|
564
567
|
|
|
568
|
+
pool = cdef.get('pool', False)
|
|
569
|
+
|
|
565
570
|
recur = incunit is not None
|
|
566
571
|
indx = self._next_indx
|
|
567
572
|
self._next_indx += 1
|
|
@@ -602,7 +607,7 @@ class Agenda(s_base.Base):
|
|
|
602
607
|
incvals = (incvals, )
|
|
603
608
|
recs.extend(ApptRec(rd, incunit, v) for (rd, v) in itertools.product(reqdicts, incvals))
|
|
604
609
|
|
|
605
|
-
appt = _Appt(self, iden, recur, indx, query, creator, recs, nexttime=nexttime, view=view, created=created)
|
|
610
|
+
appt = _Appt(self, iden, recur, indx, query, creator, recs, nexttime=nexttime, view=view, created=created, pool=pool)
|
|
606
611
|
self._addappt(iden, appt)
|
|
607
612
|
|
|
608
613
|
appt.doc = cdef.get('doc', '')
|
|
@@ -698,6 +703,13 @@ class Agenda(s_base.Base):
|
|
|
698
703
|
self.tickoff += offs
|
|
699
704
|
self._wake_event.set()
|
|
700
705
|
|
|
706
|
+
async def clearRunningStatus(self):
|
|
707
|
+
'''Used for clearing the running state at startup or change of leadership.'''
|
|
708
|
+
for appt in list(self.appts.values()):
|
|
709
|
+
if appt.isrunning:
|
|
710
|
+
logger.debug(f'Clearing the isrunning flag for {appt.iden}')
|
|
711
|
+
await self.core.addCronEdits(appt.iden, {'isrunning': False})
|
|
712
|
+
|
|
701
713
|
async def runloop(self):
|
|
702
714
|
'''
|
|
703
715
|
Task loop to issue query tasks at the right times.
|
|
@@ -808,57 +820,75 @@ class Agenda(s_base.Base):
|
|
|
808
820
|
}
|
|
809
821
|
await self.core.addCronEdits(appt.iden, edits)
|
|
810
822
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
823
|
+
logger.info(f'Agenda executing for iden={appt.iden}, name={appt.name} user={user.name}, view={appt.view}, query={appt.query}',
|
|
824
|
+
extra={'synapse': {'iden': appt.iden, 'name': appt.name, 'user': user.iden, 'text': appt.query,
|
|
825
|
+
'username': user.name, 'view': appt.view}})
|
|
826
|
+
starttime = self._getNowTick()
|
|
827
|
+
success = False
|
|
828
|
+
try:
|
|
829
|
+
opts = {
|
|
830
|
+
'user': user.iden,
|
|
831
|
+
'view': appt.view,
|
|
832
|
+
'mirror': appt.pool,
|
|
833
|
+
'vars': {'auto': {'iden': appt.iden, 'type': 'cron'}},
|
|
834
|
+
}
|
|
835
|
+
opts = self.core._initStormOpts(opts)
|
|
836
|
+
|
|
837
|
+
await self.core.feedBeholder('cron:start', {'iden': appt.iden})
|
|
838
|
+
|
|
839
|
+
async for mesg in self.core.storm(appt.query, opts=opts):
|
|
840
|
+
|
|
841
|
+
if mesg[0] == 'node':
|
|
827
842
|
count += 1
|
|
828
|
-
except asyncio.CancelledError:
|
|
829
|
-
result = 'cancelled'
|
|
830
|
-
raise
|
|
831
|
-
except Exception as e:
|
|
832
|
-
result = f'raised exception {e}'
|
|
833
|
-
logger.exception(f'Agenda job {appt.iden} {appt.name} raised exception',
|
|
834
|
-
extra={'synapse': {'iden': appt.iden, 'name': appt.name}}
|
|
835
|
-
)
|
|
836
|
-
else:
|
|
837
|
-
success = True
|
|
838
|
-
result = f'finished successfully with {count} nodes'
|
|
839
|
-
finally:
|
|
840
|
-
finishtime = self._getNowTick()
|
|
841
|
-
if not success:
|
|
842
|
-
appt.lasterrs.append(result)
|
|
843
|
-
edits = {
|
|
844
|
-
'errcount': appt.errcount + 1,
|
|
845
|
-
# we only care about the last five errors
|
|
846
|
-
'lasterrs': list(appt.lasterrs[-5:]),
|
|
847
|
-
}
|
|
848
|
-
await self.core.addCronEdits(appt.iden, edits)
|
|
849
843
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
844
|
+
elif mesg[0] == 'err':
|
|
845
|
+
excname, errinfo = mesg[1]
|
|
846
|
+
errinfo.pop('eline', None)
|
|
847
|
+
errinfo.pop('efile', None)
|
|
848
|
+
excctor = getattr(s_exc, excname, s_exc.SynErr)
|
|
849
|
+
raise excctor(**errinfo)
|
|
850
|
+
|
|
851
|
+
except asyncio.CancelledError:
|
|
852
|
+
result = 'cancelled'
|
|
853
|
+
raise
|
|
854
|
+
|
|
855
|
+
except Exception as e:
|
|
856
|
+
result = f'raised exception {e}'
|
|
857
|
+
logger.exception(f'Agenda job {appt.iden} {appt.name} raised exception',
|
|
858
|
+
extra={'synapse': {'iden': appt.iden, 'name': appt.name}}
|
|
859
|
+
)
|
|
860
|
+
else:
|
|
861
|
+
success = True
|
|
862
|
+
result = f'finished successfully with {count} nodes'
|
|
863
|
+
|
|
864
|
+
finally:
|
|
865
|
+
finishtime = self._getNowTick()
|
|
866
|
+
if not success:
|
|
867
|
+
appt.lasterrs.append(result)
|
|
855
868
|
edits = {
|
|
856
|
-
'
|
|
857
|
-
|
|
858
|
-
'
|
|
869
|
+
'errcount': appt.errcount + 1,
|
|
870
|
+
# we only care about the last five errors
|
|
871
|
+
'lasterrs': list(appt.lasterrs[-5:]),
|
|
859
872
|
}
|
|
873
|
+
|
|
874
|
+
if self.core.isactive:
|
|
875
|
+
await self.core.addCronEdits(appt.iden, edits)
|
|
876
|
+
|
|
877
|
+
took = finishtime - starttime
|
|
878
|
+
mesg = f'Agenda completed query for iden={appt.iden} name={appt.name} with result "{result}" ' \
|
|
879
|
+
f'took {took:.3f}s'
|
|
880
|
+
if not self.core.isactive:
|
|
881
|
+
mesg = mesg + ' Agenda status will not be saved since the Cortex is no longer the leader.'
|
|
882
|
+
logger.info(mesg, extra={'synapse': {'iden': appt.iden, 'name': appt.name, 'user': user.iden,
|
|
883
|
+
'result': result, 'username': user.name, 'took': took}})
|
|
884
|
+
edits = {
|
|
885
|
+
'lastfinishtime': finishtime,
|
|
886
|
+
'isrunning': False,
|
|
887
|
+
'lastresult': result,
|
|
888
|
+
}
|
|
889
|
+
if self.core.isactive:
|
|
860
890
|
await self.core.addCronEdits(appt.iden, edits)
|
|
861
891
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
892
|
+
if not self.isfini:
|
|
893
|
+
# fire beholder event before invoking nexus change (in case readonly)
|
|
894
|
+
await self.core.feedBeholder('cron:stop', {'iden': appt.iden})
|
synapse/lib/aha.py
CHANGED
|
@@ -782,6 +782,8 @@ class AhaCell(s_cell.Cell):
|
|
|
782
782
|
|
|
783
783
|
svcname, svcnetw, svcfull = self._nameAndNetwork(name, network)
|
|
784
784
|
|
|
785
|
+
logger.info(f'Deleting service [{svcfull}].', extra=await self.getLogExtra(name=svcname, netw=svcnetw))
|
|
786
|
+
|
|
785
787
|
full = ('aha', 'svcfull', svcfull)
|
|
786
788
|
path = ('aha', 'services', svcnetw, svcname)
|
|
787
789
|
|
synapse/lib/ast.py
CHANGED
|
@@ -24,7 +24,6 @@ import synapse.lib.scrape as s_scrape
|
|
|
24
24
|
import synapse.lib.msgpack as s_msgpack
|
|
25
25
|
import synapse.lib.spooled as s_spooled
|
|
26
26
|
import synapse.lib.stormctrl as s_stormctrl
|
|
27
|
-
import synapse.lib.provenance as s_provenance
|
|
28
27
|
import synapse.lib.stormtypes as s_stormtypes
|
|
29
28
|
|
|
30
29
|
from synapse.lib.stormtypes import tobool, toint, toprim, tostr, tonumber, tocmprvalu, undef
|
|
@@ -1180,33 +1179,32 @@ class CmdOper(Oper):
|
|
|
1180
1179
|
mesg = f'Command ({name}) is not marked safe for readonly use.'
|
|
1181
1180
|
raise self.addExcInfo(s_exc.IsReadOnly(mesg=mesg))
|
|
1182
1181
|
|
|
1183
|
-
|
|
1184
|
-
async def genx():
|
|
1182
|
+
async def genx():
|
|
1185
1183
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1184
|
+
async for node, path in genr:
|
|
1185
|
+
argv = await self.kids[1].compute(runt, path)
|
|
1186
|
+
if not await scmd.setArgv(argv):
|
|
1187
|
+
raise s_stormctrl.StormExit()
|
|
1190
1188
|
|
|
1191
|
-
|
|
1189
|
+
yield node, path
|
|
1192
1190
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1191
|
+
# must pull through the genr to get opts set
|
|
1192
|
+
# ( many commands expect self.opts is set at run() )
|
|
1193
|
+
genr, empty = await pullone(genx())
|
|
1196
1194
|
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1195
|
+
try:
|
|
1196
|
+
if runtsafe:
|
|
1197
|
+
argv = await self.kids[1].compute(runt, None)
|
|
1198
|
+
if not await scmd.setArgv(argv):
|
|
1199
|
+
raise s_stormctrl.StormExit()
|
|
1200
|
+
|
|
1201
|
+
if runtsafe or not empty:
|
|
1202
|
+
async with contextlib.aclosing(scmd.execStormCmd(runt, genr)) as agen:
|
|
1203
|
+
async for item in agen:
|
|
1204
|
+
yield item
|
|
1207
1205
|
|
|
1208
|
-
|
|
1209
|
-
|
|
1206
|
+
finally:
|
|
1207
|
+
await genr.aclose()
|
|
1210
1208
|
|
|
1211
1209
|
class SetVarOper(Oper):
|
|
1212
1210
|
|
synapse/lib/base.py
CHANGED
|
@@ -143,6 +143,7 @@ class Base:
|
|
|
143
143
|
self._fini_atexit = False
|
|
144
144
|
self._active_tasks = None # the set of free running tasks associated with me
|
|
145
145
|
self._context_managers = None # the set of context managers i must fini
|
|
146
|
+
self._syn_signal_tasks = None # initialized as a Set when addSignalHandlers is called.
|
|
146
147
|
|
|
147
148
|
async def postAnit(self):
|
|
148
149
|
'''
|
|
@@ -477,8 +478,6 @@ class Base:
|
|
|
477
478
|
asyncio.Task: An asyncio.Task object.
|
|
478
479
|
|
|
479
480
|
'''
|
|
480
|
-
import synapse.lib.provenance as s_provenance # avoid import cycle
|
|
481
|
-
|
|
482
481
|
if __debug__:
|
|
483
482
|
assert inspect.isawaitable(coro)
|
|
484
483
|
import synapse.lib.threads as s_threads # avoid import cycle
|
|
@@ -491,10 +490,6 @@ class Base:
|
|
|
491
490
|
|
|
492
491
|
s_scope.clone(task)
|
|
493
492
|
|
|
494
|
-
# In rare cases, (Like this function being triggered from call_soon_threadsafe), there's no task context
|
|
495
|
-
if asyncio.current_task():
|
|
496
|
-
s_provenance.dupstack(task)
|
|
497
|
-
|
|
498
493
|
def taskDone(task):
|
|
499
494
|
self._active_tasks.remove(task)
|
|
500
495
|
try:
|
|
@@ -565,14 +560,20 @@ class Base:
|
|
|
565
560
|
'''
|
|
566
561
|
Register SIGTERM/SIGINT signal handlers with the ioloop to fini this object.
|
|
567
562
|
'''
|
|
563
|
+
if self._syn_signal_tasks is None:
|
|
564
|
+
self._syn_signal_tasks = set()
|
|
568
565
|
|
|
569
566
|
def sigterm():
|
|
570
|
-
|
|
571
|
-
asyncio.create_task(self.fini())
|
|
567
|
+
logger.warning('Caught SIGTERM, shutting down.')
|
|
568
|
+
task = asyncio.create_task(self.fini())
|
|
569
|
+
self._syn_signal_tasks.add(task)
|
|
570
|
+
task.add_done_callback(self._syn_signal_tasks.discard)
|
|
572
571
|
|
|
573
572
|
def sigint():
|
|
574
|
-
|
|
575
|
-
asyncio.create_task(self.fini())
|
|
573
|
+
logger.warning('Caught SIGINT, shutting down.')
|
|
574
|
+
task = asyncio.create_task(self.fini())
|
|
575
|
+
self._syn_signal_tasks.add(task)
|
|
576
|
+
task.add_done_callback(self._syn_signal_tasks.discard)
|
|
576
577
|
|
|
577
578
|
loop = asyncio.get_running_loop()
|
|
578
579
|
loop.add_signal_handler(signal.SIGINT, sigint)
|
synapse/lib/cell.py
CHANGED
|
@@ -668,26 +668,32 @@ class CellApi(s_base.Base):
|
|
|
668
668
|
|
|
669
669
|
@adminapi()
|
|
670
670
|
async def listHiveKey(self, path=None):
|
|
671
|
+
s_common.deprecated('CellApi.listHiveKey', curv='2.167.0')
|
|
671
672
|
return await self.cell.listHiveKey(path=path)
|
|
672
673
|
|
|
673
674
|
@adminapi(log=True)
|
|
674
675
|
async def getHiveKeys(self, path):
|
|
676
|
+
s_common.deprecated('CellApi.getHiveKeys', curv='2.167.0')
|
|
675
677
|
return await self.cell.getHiveKeys(path)
|
|
676
678
|
|
|
677
679
|
@adminapi(log=True)
|
|
678
680
|
async def getHiveKey(self, path):
|
|
681
|
+
s_common.deprecated('CellApi.getHiveKey', curv='2.167.0')
|
|
679
682
|
return await self.cell.getHiveKey(path)
|
|
680
683
|
|
|
681
684
|
@adminapi(log=True)
|
|
682
685
|
async def setHiveKey(self, path, valu):
|
|
686
|
+
s_common.deprecated('CellApi.setHiveKey', curv='2.167.0')
|
|
683
687
|
return await self.cell.setHiveKey(path, valu)
|
|
684
688
|
|
|
685
689
|
@adminapi(log=True)
|
|
686
690
|
async def popHiveKey(self, path):
|
|
691
|
+
s_common.deprecated('CellApi.popHiveKey', curv='2.167.0')
|
|
687
692
|
return await self.cell.popHiveKey(path)
|
|
688
693
|
|
|
689
694
|
@adminapi(log=True)
|
|
690
695
|
async def saveHiveTree(self, path=()):
|
|
696
|
+
s_common.deprecated('CellApi.saveHiveTree', curv='2.167.0')
|
|
691
697
|
return await self.cell.saveHiveTree(path=path)
|
|
692
698
|
|
|
693
699
|
@adminapi()
|
|
@@ -1419,7 +1425,6 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
1419
1425
|
if ahaurl is not None:
|
|
1420
1426
|
|
|
1421
1427
|
info = await s_telepath.addAhaUrl(ahaurl)
|
|
1422
|
-
self.ahaclient = info.get('client')
|
|
1423
1428
|
if self.ahaclient is None:
|
|
1424
1429
|
self.ahaclient = await s_telepath.Client.anit(info.get('url'))
|
|
1425
1430
|
self.ahaclient._fini_atexit = True
|
|
@@ -1560,32 +1565,22 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
1560
1565
|
|
|
1561
1566
|
self.ahasvcname = f'{ahaname}.{ahanetw}'
|
|
1562
1567
|
|
|
1563
|
-
async def
|
|
1564
|
-
|
|
1565
|
-
|
|
1568
|
+
async def _runAhaRegLoop():
|
|
1569
|
+
|
|
1570
|
+
while not self.isfini:
|
|
1566
1571
|
try:
|
|
1572
|
+
proxy = await self.ahaclient.proxy()
|
|
1573
|
+
info = await self.getAhaInfo()
|
|
1567
1574
|
await proxy.addAhaSvc(ahaname, info, network=ahanetw)
|
|
1568
1575
|
if self.isactive and ahalead is not None:
|
|
1569
1576
|
await proxy.addAhaSvc(ahalead, info, network=ahanetw)
|
|
1577
|
+
except Exception as e:
|
|
1578
|
+
logger.exception(f'Error registering service {self.ahasvcname} with AHA: {e}')
|
|
1579
|
+
await self.waitfini(1)
|
|
1580
|
+
else:
|
|
1581
|
+
await proxy.waitfini()
|
|
1570
1582
|
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
except asyncio.CancelledError: # pragma: no cover
|
|
1574
|
-
raise
|
|
1575
|
-
|
|
1576
|
-
except Exception:
|
|
1577
|
-
logger.exception('Error in _initAhaService() onlink')
|
|
1578
|
-
|
|
1579
|
-
await proxy.waitfini(1)
|
|
1580
|
-
|
|
1581
|
-
async def fini():
|
|
1582
|
-
await self.ahaclient.offlink(onlink)
|
|
1583
|
-
|
|
1584
|
-
async def init():
|
|
1585
|
-
await self.ahaclient.onlink(onlink)
|
|
1586
|
-
self.onfini(fini)
|
|
1587
|
-
|
|
1588
|
-
self.schedCoro(init())
|
|
1583
|
+
self.schedCoro(_runAhaRegLoop())
|
|
1589
1584
|
|
|
1590
1585
|
async def initServiceRuntime(self):
|
|
1591
1586
|
pass
|
|
@@ -2905,6 +2900,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
2905
2900
|
if isnew:
|
|
2906
2901
|
path = os.path.join(self.dirn, 'hiveboot.yaml')
|
|
2907
2902
|
if os.path.isfile(path):
|
|
2903
|
+
s_common.deprdate('Initial hive config from hiveboot.yaml', '2024-05-05')
|
|
2908
2904
|
logger.debug(f'Loading cell hive from {path}')
|
|
2909
2905
|
tree = s_common.yamlload(path)
|
|
2910
2906
|
if tree is not None:
|
|
@@ -3694,7 +3690,8 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
3694
3690
|
|
|
3695
3691
|
await self.ahaclient.waitready()
|
|
3696
3692
|
|
|
3697
|
-
|
|
3693
|
+
proxy = await self.ahaclient.proxy(timeout=5)
|
|
3694
|
+
mirrors = await proxy.getAhaSvcMirrors(self.ahasvcname)
|
|
3698
3695
|
if mirrors is None:
|
|
3699
3696
|
mesg = 'Service must be configured with AHA to enumerate mirror URLs'
|
|
3700
3697
|
raise s_exc.NoSuchName(mesg=mesg, name=self.ahasvcname)
|
|
@@ -4088,7 +4085,10 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
4088
4085
|
await s_base.Base.addSignalHandlers(self)
|
|
4089
4086
|
|
|
4090
4087
|
def sighup():
|
|
4091
|
-
|
|
4088
|
+
logger.info('Caught SIGHUP, running reloadable subsystems.')
|
|
4089
|
+
task = asyncio.create_task(self.reload())
|
|
4090
|
+
self._syn_signal_tasks.add(task)
|
|
4091
|
+
task.add_done_callback(self._syn_signal_tasks.discard)
|
|
4092
4092
|
|
|
4093
4093
|
loop = asyncio.get_running_loop()
|
|
4094
4094
|
loop.add_signal_handler(signal.SIGHUP, sighup)
|
synapse/lib/hive.py
CHANGED
|
@@ -473,12 +473,15 @@ class HiveApi(s_base.Base):
|
|
|
473
473
|
self.onfini(self._onHapiFini)
|
|
474
474
|
|
|
475
475
|
async def loadHiveTree(self, tree, path=(), trim=False):
|
|
476
|
+
s_common.deprecated('HiveApi.loadHiveTree', curv='2.167.0')
|
|
476
477
|
return await self.hive.loadHiveTree(tree, path=path, trim=trim)
|
|
477
478
|
|
|
478
479
|
async def saveHiveTree(self, path=()):
|
|
480
|
+
s_common.deprecated('HiveApi.saveHiveTree', curv='2.167.0')
|
|
479
481
|
return await self.hive.saveHiveTree(path=path)
|
|
480
482
|
|
|
481
483
|
async def treeAndSync(self, path, iden):
|
|
484
|
+
s_common.deprecated('HiveApi.treeAndSync', curv='2.167.0')
|
|
482
485
|
|
|
483
486
|
node = await self.hive.open(path)
|
|
484
487
|
|
|
@@ -510,16 +513,22 @@ class HiveApi(s_base.Base):
|
|
|
510
513
|
return
|
|
511
514
|
|
|
512
515
|
async def setAndSync(self, path, valu, iden, nexs=False):
|
|
516
|
+
s_common.deprecated('HiveApi.setAndSync', curv='2.167.0')
|
|
517
|
+
|
|
513
518
|
valu = await self.hive.set(path, valu, nexs=nexs)
|
|
514
519
|
await self.msgq.put(('hive:sync', {'iden': iden}))
|
|
515
520
|
return valu
|
|
516
521
|
|
|
517
522
|
async def addAndSync(self, path, valu, iden):
|
|
523
|
+
s_common.deprecated('HiveApi.addAndSync', curv='2.167.0')
|
|
524
|
+
|
|
518
525
|
valu = await self.hive.add(path, valu)
|
|
519
526
|
await self.msgq.put(('hive:sync', {'iden': iden}))
|
|
520
527
|
return valu
|
|
521
528
|
|
|
522
529
|
async def popAndSync(self, path, iden, nexs=False):
|
|
530
|
+
s_common.deprecated('HiveApi.popAndSync', curv='2.167.0')
|
|
531
|
+
|
|
523
532
|
valu = await self.hive.pop(path, nexs=nexs)
|
|
524
533
|
await self.msgq.put(('hive:sync', {'iden': iden}))
|
|
525
534
|
return valu
|
|
@@ -531,9 +540,11 @@ class HiveApi(s_base.Base):
|
|
|
531
540
|
self.msgq.put_nowait(mesg)
|
|
532
541
|
|
|
533
542
|
async def get(self, full):
|
|
543
|
+
s_common.deprecated('HiveApi.get', curv='2.167.0')
|
|
534
544
|
return await self.hive.get(full)
|
|
535
545
|
|
|
536
546
|
async def edits(self):
|
|
547
|
+
s_common.deprecated('HiveApi.edits', curv='2.167.0')
|
|
537
548
|
|
|
538
549
|
while not self.isfini:
|
|
539
550
|
|
synapse/lib/httpapi.py
CHANGED
synapse/lib/nexus.py
CHANGED
|
@@ -589,10 +589,11 @@ class NexsRoot(s_base.Base):
|
|
|
589
589
|
|
|
590
590
|
try:
|
|
591
591
|
await self.cell.ahaclient.waitready(timeout=5)
|
|
592
|
-
|
|
592
|
+
proxy = await self.cell.ahaclient.proxy(timeout=5)
|
|
593
|
+
ahainfo = await proxy.getCellInfo()
|
|
593
594
|
ahavers = ahainfo['synapse']['version']
|
|
594
595
|
if self.cell.ahasvcname is not None and ahavers >= (2, 95, 0):
|
|
595
|
-
await
|
|
596
|
+
await proxy.modAhaSvcInfo(self.cell.ahasvcname, {'ready': status})
|
|
596
597
|
|
|
597
598
|
except asyncio.CancelledError: # pragma: no cover TODO: remove once >= py 3.8 only
|
|
598
599
|
raise
|
synapse/lib/node.py
CHANGED
|
@@ -472,10 +472,12 @@ class Node:
|
|
|
472
472
|
form=self.form.full, tag=tag)
|
|
473
473
|
|
|
474
474
|
pref = name + '.'
|
|
475
|
+
exists = self.tags.get(name, s_common.novalu) is not s_common.novalu
|
|
475
476
|
|
|
476
477
|
todel = [(len(t), t) for t in self.tags.keys() if t.startswith(pref)]
|
|
477
478
|
|
|
478
|
-
|
|
479
|
+
# only prune when we're actually deleting a tag
|
|
480
|
+
if len(path) > 1 and exists:
|
|
479
481
|
|
|
480
482
|
parent = '.'.join(path[:-1])
|
|
481
483
|
|
|
@@ -511,7 +513,7 @@ class Node:
|
|
|
511
513
|
edits.append((s_layer.EDIT_TAG_DEL, (subtag, None), ()))
|
|
512
514
|
|
|
513
515
|
edits.extend(self._getTagPropDel(name))
|
|
514
|
-
if
|
|
516
|
+
if exists:
|
|
515
517
|
edits.append((s_layer.EDIT_TAG_DEL, (name, None), ()))
|
|
516
518
|
|
|
517
519
|
return edits
|
synapse/lib/schemas.py
CHANGED
|
@@ -40,6 +40,7 @@ _HttpExtAPIConfSchema = {
|
|
|
40
40
|
'name': {'type': 'string', 'default': ''},
|
|
41
41
|
'desc': {'type': 'string', 'default': ''},
|
|
42
42
|
'path': {'type': 'string', 'minlen': 1},
|
|
43
|
+
'pool': {'type': 'boolean', 'default': False},
|
|
43
44
|
'view': {'type': 'string', 'pattern': s_config.re_iden},
|
|
44
45
|
'runas': {'type': 'string', 'pattern': '^(owner|user)$'},
|
|
45
46
|
'owner': {'type': 'string', 'pattern': s_config.re_iden},
|
|
@@ -93,6 +94,7 @@ _CronJobSchema = {
|
|
|
93
94
|
'iden': {'type': 'string', 'pattern': s_config.re_iden},
|
|
94
95
|
'view': {'type': 'string', 'pattern': s_config.re_iden},
|
|
95
96
|
'name': {'type': 'string'},
|
|
97
|
+
'pool': {'type': 'boolean'},
|
|
96
98
|
'doc': {'type': 'string'},
|
|
97
99
|
'incunit': {
|
|
98
100
|
'oneOf': [
|
|
@@ -170,7 +172,7 @@ reqValidView = s_config.getJsValidator({
|
|
|
170
172
|
'parent': {'type': ['string', 'null'], 'pattern': s_config.re_iden},
|
|
171
173
|
'creator': {'type': 'string', 'pattern': s_config.re_iden},
|
|
172
174
|
'created': {'type': 'integer', 'minimum': 0},
|
|
173
|
-
'
|
|
175
|
+
'protected': {'type': 'boolean', 'default': False},
|
|
174
176
|
'merging': {'type': 'boolean'},
|
|
175
177
|
'layers': {
|
|
176
178
|
'type': 'array',
|
synapse/lib/snap.py
CHANGED
|
@@ -209,6 +209,27 @@ class ProtoNode:
|
|
|
209
209
|
if tagnode is not s_common.novalu:
|
|
210
210
|
return self.ctx.loadNode(tagnode)
|
|
211
211
|
|
|
212
|
+
# check for an :isnow tag redirection in our hierarchy...
|
|
213
|
+
toks = info.get('toks')
|
|
214
|
+
for i in range(len(toks)):
|
|
215
|
+
|
|
216
|
+
toktag = '.'.join(toks[:i + 1])
|
|
217
|
+
toknode = await self.ctx.snap.getTagNode(toktag)
|
|
218
|
+
if toknode is s_common.novalu:
|
|
219
|
+
continue
|
|
220
|
+
|
|
221
|
+
tokvalu = toknode.ndef[1]
|
|
222
|
+
if tokvalu == toktag:
|
|
223
|
+
continue
|
|
224
|
+
|
|
225
|
+
realnow = tokvalu + norm[len(toktag):]
|
|
226
|
+
tagnode = await self.ctx.snap.getTagNode(realnow)
|
|
227
|
+
if tagnode is not s_common.novalu:
|
|
228
|
+
return self.ctx.loadNode(tagnode)
|
|
229
|
+
|
|
230
|
+
norm, info = await self.ctx.snap.getTagNorm(realnow)
|
|
231
|
+
break
|
|
232
|
+
|
|
212
233
|
return await self.ctx.addNode('syn:tag', norm, norminfo=info)
|
|
213
234
|
|
|
214
235
|
def getTag(self, tag):
|
|
@@ -657,6 +678,33 @@ class Snap(s_base.Base):
|
|
|
657
678
|
self.onfini(runt)
|
|
658
679
|
return runt
|
|
659
680
|
|
|
681
|
+
async def _joinEmbedStor(self, storage, embeds):
|
|
682
|
+
for nodePath, relProps in embeds.items():
|
|
683
|
+
await asyncio.sleep(0)
|
|
684
|
+
iden = relProps.get('*')
|
|
685
|
+
if not iden:
|
|
686
|
+
continue
|
|
687
|
+
|
|
688
|
+
stor = await self.view.getStorNodes(s_common.uhex(iden))
|
|
689
|
+
for relProp in relProps.keys():
|
|
690
|
+
await asyncio.sleep(0)
|
|
691
|
+
if relProp == '*':
|
|
692
|
+
continue
|
|
693
|
+
|
|
694
|
+
for idx, layrstor in enumerate(stor):
|
|
695
|
+
await asyncio.sleep(0)
|
|
696
|
+
props = layrstor.get('props')
|
|
697
|
+
if not props:
|
|
698
|
+
continue
|
|
699
|
+
|
|
700
|
+
if relProp not in props:
|
|
701
|
+
continue
|
|
702
|
+
|
|
703
|
+
if 'embeds' not in storage[idx]:
|
|
704
|
+
storage[idx]['embeds'] = {}
|
|
705
|
+
|
|
706
|
+
storage[idx]['embeds'][f'{nodePath}::{relProp}'] = props[relProp]
|
|
707
|
+
|
|
660
708
|
async def iterStormPodes(self, text, opts, user=None):
|
|
661
709
|
'''
|
|
662
710
|
Yield packed node tuples for the given storm query text.
|
|
@@ -699,6 +747,8 @@ class Snap(s_base.Base):
|
|
|
699
747
|
embdef = embeds.get(node.form.name)
|
|
700
748
|
if embdef is not None:
|
|
701
749
|
pode[1]['embeds'] = await node.getEmbeds(embdef)
|
|
750
|
+
if show_storage:
|
|
751
|
+
await self._joinEmbedStor(pode[1]['storage'], pode[1]['embeds'])
|
|
702
752
|
|
|
703
753
|
yield pode
|
|
704
754
|
|