synapse 2.218.1__py311-none-any.whl → 2.219.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 +113 -14
- synapse/daemon.py +2 -1
- synapse/lib/ast.py +86 -84
- synapse/lib/layer.py +27 -0
- synapse/lib/schemas.py +25 -0
- synapse/lib/stormtypes.py +138 -2
- synapse/lib/version.py +2 -2
- synapse/models/inet.py +3 -0
- synapse/tests/files/stormpkg/badinits.yaml +12 -0
- synapse/tests/files/stormpkg/testpkg.yaml +12 -0
- synapse/tests/test_lib_layer.py +119 -0
- synapse/tests/test_lib_storm.py +179 -0
- synapse/tests/test_lib_stormtypes.py +125 -0
- synapse/tests/test_model_inet.py +3 -0
- synapse/tests/test_telepath.py +31 -0
- synapse/tests/test_tools_genpkg.py +4 -0
- synapse/tests/utils.py +1 -1
- synapse/tools/genpkg.py +9 -0
- {synapse-2.218.1.dist-info → synapse-2.219.0.dist-info}/METADATA +2 -2
- {synapse-2.218.1.dist-info → synapse-2.219.0.dist-info}/RECORD +23 -22
- {synapse-2.218.1.dist-info → synapse-2.219.0.dist-info}/WHEEL +0 -0
- {synapse-2.218.1.dist-info → synapse-2.219.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.218.1.dist-info → synapse-2.219.0.dist-info}/top_level.txt +0 -0
synapse/lib/stormtypes.py
CHANGED
|
@@ -2,7 +2,6 @@ import bz2
|
|
|
2
2
|
import copy
|
|
3
3
|
import gzip
|
|
4
4
|
import time
|
|
5
|
-
|
|
6
5
|
import regex
|
|
7
6
|
import types
|
|
8
7
|
import base64
|
|
@@ -10,6 +9,7 @@ import pprint
|
|
|
10
9
|
import struct
|
|
11
10
|
import asyncio
|
|
12
11
|
import decimal
|
|
12
|
+
import hashlib
|
|
13
13
|
import inspect
|
|
14
14
|
import logging
|
|
15
15
|
import binascii
|
|
@@ -730,6 +730,18 @@ class LibPkg(Lib):
|
|
|
730
730
|
{'name': 'pkgdef', 'type': 'dict', 'desc': 'A Storm Package definition.', },
|
|
731
731
|
),
|
|
732
732
|
'returns': {'type': 'dict', 'desc': 'A dictionary listing dependencies and if they are met.', }}},
|
|
733
|
+
{'name': 'vars',
|
|
734
|
+
'desc': "Get a dictionary representing the package's persistent variables.",
|
|
735
|
+
'type': {'type': 'function', '_funcname': '_libPkgVars',
|
|
736
|
+
'args': (
|
|
737
|
+
{'name': 'name', 'type': 'str',
|
|
738
|
+
'desc': 'A Storm Package name to get vars for.', },
|
|
739
|
+
),
|
|
740
|
+
'returns': {'type': 'pkg:vars', 'desc': 'A dictionary representing the package variables.', }}},
|
|
741
|
+
)
|
|
742
|
+
_storm_lib_perms = (
|
|
743
|
+
{'perm': ('power-ups', '<name>', 'admin'), 'gate': 'cortex',
|
|
744
|
+
'desc': 'Controls the ability to interact with the vars for a Storm Package by name.'},
|
|
733
745
|
)
|
|
734
746
|
_storm_lib_path = ('pkg',)
|
|
735
747
|
|
|
@@ -741,6 +753,7 @@ class LibPkg(Lib):
|
|
|
741
753
|
'del': self._libPkgDel,
|
|
742
754
|
'list': self._libPkgList,
|
|
743
755
|
'deps': self._libPkgDeps,
|
|
756
|
+
'vars': self._libPkgVars,
|
|
744
757
|
}
|
|
745
758
|
|
|
746
759
|
async def _libPkgAdd(self, pkgdef, verify=False):
|
|
@@ -780,6 +793,11 @@ class LibPkg(Lib):
|
|
|
780
793
|
pkgdef = await toprim(pkgdef)
|
|
781
794
|
return await self.runt.snap.core.verifyStormPkgDeps(pkgdef)
|
|
782
795
|
|
|
796
|
+
async def _libPkgVars(self, name):
|
|
797
|
+
name = await tostr(name)
|
|
798
|
+
confirm(('power-ups', name, 'admin'))
|
|
799
|
+
return PkgVars(self.runt, name)
|
|
800
|
+
|
|
783
801
|
@registry.registerLib
|
|
784
802
|
class LibDmon(Lib):
|
|
785
803
|
'''
|
|
@@ -2745,9 +2763,13 @@ class LibAxon(Lib):
|
|
|
2745
2763
|
|
|
2746
2764
|
self.runt.confirm(('axon', 'upload'))
|
|
2747
2765
|
|
|
2766
|
+
sha256 = hashlib.sha256(byts).digest()
|
|
2767
|
+
|
|
2748
2768
|
await self.runt.snap.core.getAxon()
|
|
2749
|
-
|
|
2769
|
+
if await self.runt.snap.core.axon.has(sha256):
|
|
2770
|
+
return (len(byts), s_common.ehex(sha256))
|
|
2750
2771
|
|
|
2772
|
+
size, sha256 = await self.runt.snap.core.axon.put(byts)
|
|
2751
2773
|
return (size, s_common.ehex(sha256))
|
|
2752
2774
|
|
|
2753
2775
|
@stormfunc(readonly=True)
|
|
@@ -6015,6 +6037,45 @@ class LibVars(Lib):
|
|
|
6015
6037
|
async def _libVarsType(self, valu):
|
|
6016
6038
|
return await totype(valu)
|
|
6017
6039
|
|
|
6040
|
+
@registry.registerType
|
|
6041
|
+
class PkgVars(Prim):
|
|
6042
|
+
'''
|
|
6043
|
+
The Storm deref/setitem/iter convention on top of pkg vars information.
|
|
6044
|
+
'''
|
|
6045
|
+
_storm_typename = 'pkg:vars'
|
|
6046
|
+
_ismutable = True
|
|
6047
|
+
|
|
6048
|
+
def __init__(self, runt, valu, path=None):
|
|
6049
|
+
Prim.__init__(self, valu, path=path)
|
|
6050
|
+
self.runt = runt
|
|
6051
|
+
|
|
6052
|
+
def _reqPkgAdmin(self):
|
|
6053
|
+
confirm(('power-ups', self.valu, 'admin'))
|
|
6054
|
+
|
|
6055
|
+
@stormfunc(readonly=True)
|
|
6056
|
+
async def deref(self, name):
|
|
6057
|
+
self._reqPkgAdmin()
|
|
6058
|
+
name = await tostr(name)
|
|
6059
|
+
return await self.runt.snap.core.getStormPkgVar(self.valu, name)
|
|
6060
|
+
|
|
6061
|
+
async def setitem(self, name, valu):
|
|
6062
|
+
self._reqPkgAdmin()
|
|
6063
|
+
name = await tostr(name)
|
|
6064
|
+
|
|
6065
|
+
if valu is undef:
|
|
6066
|
+
await self.runt.snap.core.popStormPkgVar(self.valu, name)
|
|
6067
|
+
return
|
|
6068
|
+
|
|
6069
|
+
valu = await toprim(valu)
|
|
6070
|
+
await self.runt.snap.core.setStormPkgVar(self.valu, name, valu)
|
|
6071
|
+
|
|
6072
|
+
@stormfunc(readonly=True)
|
|
6073
|
+
async def iter(self):
|
|
6074
|
+
self._reqPkgAdmin()
|
|
6075
|
+
async for name, valu in self.runt.snap.core.iterStormPkgVars(self.valu):
|
|
6076
|
+
yield name, valu
|
|
6077
|
+
await asyncio.sleep(0)
|
|
6078
|
+
|
|
6018
6079
|
@registry.registerType
|
|
6019
6080
|
class Query(Prim):
|
|
6020
6081
|
'''
|
|
@@ -7069,6 +7130,37 @@ class Layer(Prim):
|
|
|
7069
7130
|
'desc': 'The name of the form to get storage nodes for.'},
|
|
7070
7131
|
),
|
|
7071
7132
|
'returns': {'name': 'Yields', 'type': 'list', 'desc': 'Tuple of buid, sode values.', }}},
|
|
7133
|
+
{'name': 'getStorNodesByProp', 'desc': '''
|
|
7134
|
+
Get buid, sode tuples representing the data stored in the layer for a given property.
|
|
7135
|
+
Notes:
|
|
7136
|
+
The storage nodes represent **only** the data stored in the layer
|
|
7137
|
+
and may not represent whole nodes.
|
|
7138
|
+
''',
|
|
7139
|
+
'type': {'type': 'function', '_funcname': 'getStorNodesByProp',
|
|
7140
|
+
'args': (
|
|
7141
|
+
{'name': 'propname', 'type': 'str', 'desc': 'The full property name to lift by.'},
|
|
7142
|
+
{'name': 'propvalu', 'type': 'obj', 'desc': 'The value for the property.', 'default': None},
|
|
7143
|
+
{'name': 'propcmpr', 'type': 'str', 'desc': 'The comparison operation to use on the value.',
|
|
7144
|
+
'default': '='},
|
|
7145
|
+
),
|
|
7146
|
+
'returns': {'name': 'Yields', 'type': 'list', 'desc': 'Tuple of buid, sode values.', }}},
|
|
7147
|
+
{'name': 'setStorNodeProp',
|
|
7148
|
+
'desc': 'Set a property on a node in this layer.',
|
|
7149
|
+
'type': {'type': 'function', '_funcname': 'setStorNodeProp',
|
|
7150
|
+
'args': (
|
|
7151
|
+
{'name': 'nodeid', 'type': 'str', 'desc': 'The hex string of the node iden.'},
|
|
7152
|
+
{'name': 'prop', 'type': 'str', 'desc': 'The property name to set.'},
|
|
7153
|
+
{'name': 'valu', 'type': 'any', 'desc': 'The value to set.'},
|
|
7154
|
+
),
|
|
7155
|
+
'returns': {'type': 'boolean', 'desc': 'Returns true if edits were made.'}}},
|
|
7156
|
+
{'name': 'delStorNodeProp',
|
|
7157
|
+
'desc': 'Delete a property from a node in this layer.',
|
|
7158
|
+
'type': {'type': 'function', '_funcname': 'delStorNodeProp',
|
|
7159
|
+
'args': (
|
|
7160
|
+
{'name': 'nodeid', 'type': 'str', 'desc': 'The hex string of the node iden.'},
|
|
7161
|
+
{'name': 'prop', 'type': 'str', 'desc': 'The property name to delete.'},
|
|
7162
|
+
),
|
|
7163
|
+
'returns': {'type': 'boolean', 'desc': 'Returns true if edits were made.'}}},
|
|
7072
7164
|
{'name': 'getMirrorStatus', 'desc': '''
|
|
7073
7165
|
Return a dictionary of the mirror synchronization status for the layer.
|
|
7074
7166
|
''',
|
|
@@ -7287,10 +7379,13 @@ class Layer(Prim):
|
|
|
7287
7379
|
'getStorNode': self.getStorNode,
|
|
7288
7380
|
'getStorNodes': self.getStorNodes,
|
|
7289
7381
|
'getStorNodesByForm': self.getStorNodesByForm,
|
|
7382
|
+
'getStorNodesByProp': self.getStorNodesByProp,
|
|
7290
7383
|
'getEdgesByN1': self.getEdgesByN1,
|
|
7291
7384
|
'getEdgesByN2': self.getEdgesByN2,
|
|
7292
7385
|
'getNodeData': self.getNodeData,
|
|
7293
7386
|
'getMirrorStatus': self.getMirrorStatus,
|
|
7387
|
+
'setStorNodeProp': self.setStorNodeProp,
|
|
7388
|
+
'delStorNodeProp': self.delStorNodeProp,
|
|
7294
7389
|
}
|
|
7295
7390
|
|
|
7296
7391
|
@stormfunc(readonly=True)
|
|
@@ -7364,6 +7459,25 @@ class Layer(Prim):
|
|
|
7364
7459
|
layr = self.runt.snap.core.getLayer(iden)
|
|
7365
7460
|
return await layr.getMirrorStatus()
|
|
7366
7461
|
|
|
7462
|
+
async def setStorNodeProp(self, nodeid, prop, valu):
|
|
7463
|
+
iden = self.valu.get('iden')
|
|
7464
|
+
layr = self.runt.snap.core.getLayer(iden)
|
|
7465
|
+
buid = s_common.uhex(await tostr(nodeid))
|
|
7466
|
+
prop = await tostr(prop)
|
|
7467
|
+
valu = await tostor(valu)
|
|
7468
|
+
self.runt.reqAdmin(mesg='setStorNodeProp() requires admin privileges.')
|
|
7469
|
+
meta = {'time': s_common.now(), 'user': self.runt.user.iden}
|
|
7470
|
+
return await layr.setStorNodeProp(buid, prop, valu, meta=meta)
|
|
7471
|
+
|
|
7472
|
+
async def delStorNodeProp(self, nodeid, prop):
|
|
7473
|
+
iden = self.valu.get('iden')
|
|
7474
|
+
layr = self.runt.snap.core.getLayer(iden)
|
|
7475
|
+
buid = s_common.uhex(await tostr(nodeid))
|
|
7476
|
+
prop = await tostr(prop)
|
|
7477
|
+
self.runt.reqAdmin(mesg='delStorNodeProp() requires admin privileges.')
|
|
7478
|
+
meta = {'time': s_common.now(), 'user': self.runt.user.iden}
|
|
7479
|
+
return await layr.delStorNodeProp(buid, prop, meta=meta)
|
|
7480
|
+
|
|
7367
7481
|
async def _addPull(self, url, offs=0, queue_size=s_const.layer_pdef_qsize, chunk_size=s_const.layer_pdef_csize):
|
|
7368
7482
|
url = await tostr(url)
|
|
7369
7483
|
offs = await toint(offs)
|
|
@@ -7646,6 +7760,28 @@ class Layer(Prim):
|
|
|
7646
7760
|
async for item in layr.getStorNodesByForm(form):
|
|
7647
7761
|
yield item
|
|
7648
7762
|
|
|
7763
|
+
@stormfunc(readonly=True)
|
|
7764
|
+
async def getStorNodesByProp(self, propname, propvalu=None, propcmpr='='):
|
|
7765
|
+
propname = await tostr(propname)
|
|
7766
|
+
propvalu = await tostor(propvalu)
|
|
7767
|
+
propcmpr = await tostr(propcmpr)
|
|
7768
|
+
|
|
7769
|
+
layriden = self.valu.get('iden')
|
|
7770
|
+
await self.runt.reqUserCanReadLayer(layriden)
|
|
7771
|
+
layr = self.runt.snap.core.getLayer(layriden)
|
|
7772
|
+
|
|
7773
|
+
prop = self.runt.snap.core.model.reqProp(propname)
|
|
7774
|
+
|
|
7775
|
+
if propvalu is not None:
|
|
7776
|
+
norm, info = prop.type.norm(propvalu)
|
|
7777
|
+
cmprvals = prop.type.getStorCmprs(propcmpr, norm)
|
|
7778
|
+
async for _, buid, sode in layr.liftByPropValu(prop.form.name, prop.name, cmprvals):
|
|
7779
|
+
yield (s_common.ehex(buid), sode)
|
|
7780
|
+
return
|
|
7781
|
+
|
|
7782
|
+
async for _, buid, sode in layr.liftByProp(prop.form.name, prop.name):
|
|
7783
|
+
yield (s_common.ehex(buid), sode)
|
|
7784
|
+
|
|
7649
7785
|
@stormfunc(readonly=True)
|
|
7650
7786
|
async def getEdges(self):
|
|
7651
7787
|
layriden = self.valu.get('iden')
|
synapse/lib/version.py
CHANGED
|
@@ -223,6 +223,6 @@ def reqVersion(valu, reqver,
|
|
|
223
223
|
##############################################################################
|
|
224
224
|
# The following are touched during the release process by bumpversion.
|
|
225
225
|
# Do not modify these directly.
|
|
226
|
-
version = (2,
|
|
226
|
+
version = (2, 219, 0)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
228
|
+
commit = '9e442b257a7ddfa8d476eafdcad21c3a0440cc83'
|
synapse/models/inet.py
CHANGED
|
@@ -3796,6 +3796,9 @@ class InetModule(s_module.CoreModule):
|
|
|
3796
3796
|
('user', ('inet:user', {}), {
|
|
3797
3797
|
'doc': 'The current user name of the account.'}),
|
|
3798
3798
|
|
|
3799
|
+
('parent', ('inet:service:account', {}), {
|
|
3800
|
+
'doc': 'A parent account which owns this account.'}),
|
|
3801
|
+
|
|
3799
3802
|
('email', ('inet:email', {}), {
|
|
3800
3803
|
'doc': 'The current email address associated with the account.'}),
|
|
3801
3804
|
|
|
@@ -45,6 +45,18 @@ onload: |
|
|
|
45
45
|
$lib.time.sleep($lib.globals.get(onload_sleep, 0))
|
|
46
46
|
$lib.globals.set(testpkg, testpkg-done)
|
|
47
47
|
|
|
48
|
+
inits:
|
|
49
|
+
key: testpkg:version
|
|
50
|
+
versions:
|
|
51
|
+
- name: first
|
|
52
|
+
version: 0
|
|
53
|
+
inaugural: true
|
|
54
|
+
query: "$lib.globals.set(testpkg-first, (true))"
|
|
55
|
+
- name: second
|
|
56
|
+
desc: Another init
|
|
57
|
+
version: 2
|
|
58
|
+
query: "$lib.globals.set(testpkg-second, (true))"
|
|
59
|
+
|
|
48
60
|
external_modules:
|
|
49
61
|
- name: testext
|
|
50
62
|
package: synapse.tests.files
|
synapse/tests/test_lib_layer.py
CHANGED
|
@@ -2283,3 +2283,122 @@ class LayerTest(s_t_utils.SynTest):
|
|
|
2283
2283
|
|
|
2284
2284
|
sodes = await s_t_utils.alist(layr00.getStorNodesByForm('inet:ipv4'))
|
|
2285
2285
|
self.len(0, sodes)
|
|
2286
|
+
|
|
2287
|
+
async def test_layer_migrate_props_fork(self):
|
|
2288
|
+
|
|
2289
|
+
async with self.getTestCore() as core:
|
|
2290
|
+
|
|
2291
|
+
iden = (await core.addUser('lowuser')).get('iden')
|
|
2292
|
+
lowuser = {'user': iden}
|
|
2293
|
+
|
|
2294
|
+
fork00 = await core.view.fork()
|
|
2295
|
+
layr00 = core.getLayer(fork00['layers'][0]['iden'])
|
|
2296
|
+
|
|
2297
|
+
await core.nodes('''
|
|
2298
|
+
for $prop in (_custom:risk:level, _custom:risk:severity) {
|
|
2299
|
+
$lib.model.ext.addFormProp(
|
|
2300
|
+
test:guid,
|
|
2301
|
+
$prop,
|
|
2302
|
+
(["int", {"enums": [[10, "low"], [20, "medium"], [30, "high"]]}]),
|
|
2303
|
+
({"doc": "hey now"}),
|
|
2304
|
+
)
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
''')
|
|
2308
|
+
self.len(1, await core.nodes('syn:prop=test:guid:_custom:risk:level'))
|
|
2309
|
+
self.len(1, await core.nodes('syn:prop=test:guid:_custom:risk:severity'))
|
|
2310
|
+
|
|
2311
|
+
await core.nodes('[ test:guid=* :name=test1 :_custom:risk:level=low ]', opts={'view': fork00['iden']})
|
|
2312
|
+
|
|
2313
|
+
await core.getView(fork00['iden']).delete()
|
|
2314
|
+
|
|
2315
|
+
with self.raises(s_exc.CantDelProp) as cm:
|
|
2316
|
+
await core.callStorm('''
|
|
2317
|
+
$fullprop = "test:guid:_custom:risk:level"
|
|
2318
|
+
for $view in $lib.view.list(deporder=$lib.true) {
|
|
2319
|
+
view.exec $view.iden {
|
|
2320
|
+
yield $lib.layer.get().liftByProp($fullprop)
|
|
2321
|
+
$repr = $node.repr("_custom:risk:level")
|
|
2322
|
+
[ :severity=$repr -:_custom:risk:level ]
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2325
|
+
$lib.model.ext.delFormProp("test:guid", "_custom:risk:level")
|
|
2326
|
+
''')
|
|
2327
|
+
self.isin('Nodes still exist with prop: test:guid:_custom:risk:level', str(cm.exception))
|
|
2328
|
+
self.len(1, await core.nodes('syn:prop=test:guid:_custom:risk:level'))
|
|
2329
|
+
|
|
2330
|
+
with self.raises(s_exc.NoSuchProp) as cm:
|
|
2331
|
+
await core.callStorm('''
|
|
2332
|
+
$layer = $lib.layer.get()
|
|
2333
|
+
$layer.getStorNodesByProp("foo:bar:_custom:risk:level")
|
|
2334
|
+
''')
|
|
2335
|
+
self.isin('No property named', str(cm.exception))
|
|
2336
|
+
|
|
2337
|
+
with self.raises(s_exc.NoSuchProp):
|
|
2338
|
+
await core.callStorm('''
|
|
2339
|
+
$fullprop = "test:guid:_custom:risk:level"
|
|
2340
|
+
for $layer in $lib.layer.list() {
|
|
2341
|
+
for ($buid, $sode) in $layer.getStorNodesByProp($fullprop) {
|
|
2342
|
+
$oldv = $sode.props."_custom:risk:level"
|
|
2343
|
+
$layer.setStorNodeProp($buid, "foo:bar:severity", $oldv.0)
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
''')
|
|
2347
|
+
|
|
2348
|
+
with self.raises(s_exc.BadTypeValu):
|
|
2349
|
+
await core.callStorm('''
|
|
2350
|
+
$fullprop = "test:guid:_custom:risk:level"
|
|
2351
|
+
for $layer in $lib.layer.list() {
|
|
2352
|
+
for ($buid, $sode) in $layer.getStorNodesByProp($fullprop) {
|
|
2353
|
+
$layer.setStorNodeProp($buid, $fullprop, "newp")
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
''')
|
|
2357
|
+
|
|
2358
|
+
with self.raises(s_exc.NoSuchProp):
|
|
2359
|
+
await core.callStorm('''
|
|
2360
|
+
$fullprop = "test:guid:_custom:risk:level"
|
|
2361
|
+
for $layer in $lib.layer.list() {
|
|
2362
|
+
for ($buid, $sode) in $layer.getStorNodesByProp($fullprop) {
|
|
2363
|
+
$layer.delStorNodeProp($buid, "foo:bar:severity")
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
''')
|
|
2367
|
+
|
|
2368
|
+
with self.raises(s_exc.AuthDeny) as cm:
|
|
2369
|
+
await core.callStorm('''
|
|
2370
|
+
$buid = "8c454b27df9c0ba109c123265b50869759bccac5bbec83b41992b4e91207f4a4"
|
|
2371
|
+
$layer = $lib.layer.get()
|
|
2372
|
+
$layer.setStorNodeProp($buid, "foo:bar:severity", "newp")
|
|
2373
|
+
''', opts=lowuser)
|
|
2374
|
+
self.isin('requires admin privileges', str(cm.exception))
|
|
2375
|
+
|
|
2376
|
+
with self.raises(s_exc.AuthDeny) as cm:
|
|
2377
|
+
await core.callStorm('''
|
|
2378
|
+
$buid = "8c454b27df9c0ba109c123265b50869759bccac5bbec83b41992b4e91207f4a4"
|
|
2379
|
+
$layer = $lib.layer.get()
|
|
2380
|
+
$layer.delStorNodeProp($buid, "foo:bar:severity")
|
|
2381
|
+
''', opts=lowuser)
|
|
2382
|
+
self.isin('requires admin privileges', str(cm.exception))
|
|
2383
|
+
|
|
2384
|
+
await core.callStorm('''
|
|
2385
|
+
$fullprop = "test:guid:_custom:risk:level"
|
|
2386
|
+
for $layer in $lib.layer.list() {
|
|
2387
|
+
if $layer.getPropCount($fullprop, maxsize=1) {
|
|
2388
|
+
for ($buid, $sode) in $layer.getStorNodesByProp($fullprop, (10), "=") {
|
|
2389
|
+
$oldv = $sode.props."_custom:risk:level"
|
|
2390
|
+
$layer.setStorNodeProp($buid, "test:guid:_custom:risk:severity", $oldv.0)
|
|
2391
|
+
$layer.delStorNodeProp($buid, $fullprop)
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
$lib.model.ext.delFormProp("test:guid", "_custom:risk:level")
|
|
2396
|
+
''')
|
|
2397
|
+
self.len(0, await core.nodes('syn:prop=test:guid:_custom:risk:level'))
|
|
2398
|
+
self.len(0, await core.nodes('test:guid:_custom:risk:severity'))
|
|
2399
|
+
|
|
2400
|
+
view00 = (await core.addView(vdef={'layers': [layr00.iden]}))['iden']
|
|
2401
|
+
nodes = await core.nodes('test:guid', opts={'view': view00})
|
|
2402
|
+
self.len(1, nodes)
|
|
2403
|
+
self.none(nodes[0].props.get('_custom:risk:level'))
|
|
2404
|
+
self.eq(nodes[0].props.get('_custom:risk:severity'), 10)
|
synapse/tests/test_lib_storm.py
CHANGED
|
@@ -3105,6 +3105,185 @@ class StormTest(s_t_utils.SynTest):
|
|
|
3105
3105
|
|
|
3106
3106
|
await core00.waitfini()
|
|
3107
3107
|
|
|
3108
|
+
async def test_storm_pkg_inits(self):
|
|
3109
|
+
|
|
3110
|
+
async def loadPkg(core, pkg):
|
|
3111
|
+
waiter = core.waiter(2, 'core:pkg:onload:start', 'core:pkg:onload:complete')
|
|
3112
|
+
|
|
3113
|
+
await core.addStormPkg(pkg)
|
|
3114
|
+
|
|
3115
|
+
events = await waiter.wait(timeout=10)
|
|
3116
|
+
self.eq(events, [
|
|
3117
|
+
('core:pkg:onload:start', {'pkg': 'testload'}),
|
|
3118
|
+
('core:pkg:onload:complete', {'pkg': 'testload'}),
|
|
3119
|
+
])
|
|
3120
|
+
|
|
3121
|
+
with self.getTestDir() as dirn:
|
|
3122
|
+
|
|
3123
|
+
async with self.getTestCore(dirn=dirn) as core:
|
|
3124
|
+
|
|
3125
|
+
pkg = {
|
|
3126
|
+
'name': 'testload',
|
|
3127
|
+
'version': '0.1.0',
|
|
3128
|
+
'inits': {
|
|
3129
|
+
'key': 'testload:version',
|
|
3130
|
+
'versions': [
|
|
3131
|
+
{
|
|
3132
|
+
'version': 0,
|
|
3133
|
+
'name': 'init00',
|
|
3134
|
+
'query': '$lib.globals.set(init00, $lib.time.now())',
|
|
3135
|
+
},
|
|
3136
|
+
{
|
|
3137
|
+
'version': 1,
|
|
3138
|
+
'name': 'init01',
|
|
3139
|
+
'inaugural': True,
|
|
3140
|
+
'query': '$lib.globals.set(init01, $lib.time.now())',
|
|
3141
|
+
},
|
|
3142
|
+
]
|
|
3143
|
+
},
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
# bad init queries fail on load
|
|
3147
|
+
|
|
3148
|
+
pkg['inits']['versions'].append({
|
|
3149
|
+
'version': 2,
|
|
3150
|
+
'name': 'bad',
|
|
3151
|
+
'query': '...',
|
|
3152
|
+
})
|
|
3153
|
+
|
|
3154
|
+
await self.asyncraises(s_exc.BadSyntax, core.addStormPkg(pkg))
|
|
3155
|
+
|
|
3156
|
+
pkg['inits']['versions'].pop(2)
|
|
3157
|
+
|
|
3158
|
+
# non-increasing init versions fail on load
|
|
3159
|
+
|
|
3160
|
+
pkg['inits']['versions'].append({
|
|
3161
|
+
'version': 0,
|
|
3162
|
+
'name': 'bad',
|
|
3163
|
+
'query': '$lib.print("")',
|
|
3164
|
+
})
|
|
3165
|
+
|
|
3166
|
+
await self.asyncraises(s_exc.BadPkgDef, core.addStormPkg(pkg))
|
|
3167
|
+
|
|
3168
|
+
pkg['inits']['versions'].pop(2)
|
|
3169
|
+
|
|
3170
|
+
# only inaugural inits run on first load
|
|
3171
|
+
|
|
3172
|
+
await loadPkg(core, pkg)
|
|
3173
|
+
|
|
3174
|
+
self.eq(1, await core.getStormPkgVar('testload', 'testload:version'))
|
|
3175
|
+
self.none(await core.getStormVar('init00'))
|
|
3176
|
+
self.nn(init01 := await core.getStormVar('init01'))
|
|
3177
|
+
|
|
3178
|
+
# non-inaugural inits run on reload
|
|
3179
|
+
# inits always run before onload
|
|
3180
|
+
|
|
3181
|
+
pkg['version'] = '0.2.0'
|
|
3182
|
+
pkg['onload'] = '$lib.time.sleep((0.1)) $lib.globals.set(onload, $lib.time.now())'
|
|
3183
|
+
pkg['inits']['versions'].append({
|
|
3184
|
+
'version': 2,
|
|
3185
|
+
'name': 'init02',
|
|
3186
|
+
'query': '$lib.globals.set(init02, $lib.time.now())',
|
|
3187
|
+
})
|
|
3188
|
+
|
|
3189
|
+
await loadPkg(core, pkg)
|
|
3190
|
+
|
|
3191
|
+
self.eq(2, await core.getStormPkgVar('testload', 'testload:version'))
|
|
3192
|
+
self.none(await core.getStormVar('init00'))
|
|
3193
|
+
self.eq(init01, await core.getStormVar('init01'))
|
|
3194
|
+
self.nn(init02 := await core.getStormVar('init02'))
|
|
3195
|
+
self.nn(onload := await core.getStormVar('onload'))
|
|
3196
|
+
self.gt(onload, init02)
|
|
3197
|
+
|
|
3198
|
+
# inits run even if onload fails
|
|
3199
|
+
# prior inits do not re-run
|
|
3200
|
+
|
|
3201
|
+
pkg['version'] = '0.3.0'
|
|
3202
|
+
pkg['onload'] = '$lib.raise(SynErr, whoopsie)'
|
|
3203
|
+
pkg['inits']['versions'].append({
|
|
3204
|
+
'version': 3,
|
|
3205
|
+
'name': 'init03',
|
|
3206
|
+
'inaugural': True,
|
|
3207
|
+
'query': '$lib.globals.set(init03, $lib.time.now())',
|
|
3208
|
+
})
|
|
3209
|
+
|
|
3210
|
+
await loadPkg(core, pkg)
|
|
3211
|
+
|
|
3212
|
+
self.eq(3, await core.getStormPkgVar('testload', 'testload:version'))
|
|
3213
|
+
self.eq(init02, await core.getStormVar('init02'))
|
|
3214
|
+
self.nn(await core.getStormVar('init03'))
|
|
3215
|
+
|
|
3216
|
+
# init failure stops progression
|
|
3217
|
+
|
|
3218
|
+
await core.setStormVar('dofail', True)
|
|
3219
|
+
|
|
3220
|
+
pkg['version'] = '0.4.0'
|
|
3221
|
+
pkg['onload'] = '$lib.globals.set(onload, $lib.time.now()) $lib.time.sleep((0.1))'
|
|
3222
|
+
pkg['inits']['versions'].extend([
|
|
3223
|
+
{
|
|
3224
|
+
'version': 4,
|
|
3225
|
+
'name': 'init04',
|
|
3226
|
+
'query': '''
|
|
3227
|
+
if $lib.globals.get(dofail) { $lib.raise(SynErr, newp) }
|
|
3228
|
+
$lib.globals.set(init04, $lib.time.now())
|
|
3229
|
+
''',
|
|
3230
|
+
},
|
|
3231
|
+
{
|
|
3232
|
+
'version': 6,
|
|
3233
|
+
'name': 'init06',
|
|
3234
|
+
'query': '$lib.globals.set(init06, $lib.time.now())',
|
|
3235
|
+
},
|
|
3236
|
+
])
|
|
3237
|
+
|
|
3238
|
+
mesg = 'testload init vers=4 output: (\'SynErr\''
|
|
3239
|
+
with self.getAsyncLoggerStream('synapse.cortex', mesg) as stream:
|
|
3240
|
+
await loadPkg(core, pkg)
|
|
3241
|
+
self.eq(3, await core.getStormPkgVar('testload', 'testload:version'))
|
|
3242
|
+
await stream.wait(timeout=10)
|
|
3243
|
+
|
|
3244
|
+
self.none(await core.getStormVar('init04'))
|
|
3245
|
+
self.none(await core.getStormVar('init06'))
|
|
3246
|
+
|
|
3247
|
+
await core.setStormVar('dofail', False)
|
|
3248
|
+
|
|
3249
|
+
with self.getAsyncLoggerStream('synapse.cortex', 'testload finished onload') as stream:
|
|
3250
|
+
async with self.getTestCore(dirn=dirn) as core:
|
|
3251
|
+
await stream.wait(timeout=10)
|
|
3252
|
+
|
|
3253
|
+
# prior versions dont re-run, but a failed one does
|
|
3254
|
+
|
|
3255
|
+
self.eq(6, await core.getStormPkgVar('testload', 'testload:version'))
|
|
3256
|
+
self.gt(await core.getStormVar('onload'), onload)
|
|
3257
|
+
self.eq(init02, await core.getStormVar('init02'))
|
|
3258
|
+
self.nn(await core.getStormVar('init04'))
|
|
3259
|
+
self.nn(await core.getStormVar('init06'))
|
|
3260
|
+
|
|
3261
|
+
# coverage for prints and warns
|
|
3262
|
+
|
|
3263
|
+
pkg['version'] = '0.5.0'
|
|
3264
|
+
pkg['inits']['versions'].append({
|
|
3265
|
+
'version': 7,
|
|
3266
|
+
'name': 'init07',
|
|
3267
|
+
'query': '$lib.print("doing a print")',
|
|
3268
|
+
})
|
|
3269
|
+
|
|
3270
|
+
with self.getAsyncLoggerStream('synapse.cortex', 'doing a print') as stream:
|
|
3271
|
+
await loadPkg(core, pkg)
|
|
3272
|
+
await stream.wait(timeout=10)
|
|
3273
|
+
self.eq(7, await core.getStormPkgVar('testload', 'testload:version'))
|
|
3274
|
+
|
|
3275
|
+
pkg['version'] = '0.6.0'
|
|
3276
|
+
pkg['inits']['versions'].append({
|
|
3277
|
+
'version': 8,
|
|
3278
|
+
'name': 'init08',
|
|
3279
|
+
'query': '$lib.warn("doing a warn")',
|
|
3280
|
+
})
|
|
3281
|
+
|
|
3282
|
+
with self.getAsyncLoggerStream('synapse.cortex', 'doing a warn') as stream:
|
|
3283
|
+
await loadPkg(core, pkg)
|
|
3284
|
+
await stream.wait(timeout=10)
|
|
3285
|
+
self.eq(8, await core.getStormPkgVar('testload', 'testload:version'))
|
|
3286
|
+
|
|
3108
3287
|
async def test_storm_tree(self):
|
|
3109
3288
|
|
|
3110
3289
|
async with self.getTestCore() as core:
|