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
|
@@ -53,6 +53,27 @@ class MacroTest(s_test.SynTest):
|
|
|
53
53
|
with self.raises(s_exc.AuthDeny):
|
|
54
54
|
await core.nodes('$lib.macro.del(hehe)', opts=asvisi)
|
|
55
55
|
|
|
56
|
+
with self.raises(s_exc.BadArg):
|
|
57
|
+
await core.nodes('$lib.macro.set("", ${ inet:ipv4 })')
|
|
58
|
+
|
|
59
|
+
with self.raises(s_exc.BadArg):
|
|
60
|
+
await core.nodes('$lib.macro.get("")')
|
|
61
|
+
|
|
62
|
+
with self.raises(s_exc.BadArg):
|
|
63
|
+
await core.nodes('$lib.macro.del("")')
|
|
64
|
+
|
|
65
|
+
with self.raises(s_exc.BadArg):
|
|
66
|
+
await core.delStormMacro('', user=None)
|
|
67
|
+
|
|
68
|
+
with self.raises(s_exc.BadArg):
|
|
69
|
+
await core.nodes('$lib.macro.grant("", users, hehe, 3)')
|
|
70
|
+
|
|
71
|
+
with self.raises(s_exc.SchemaViolation):
|
|
72
|
+
await core.nodes('$lib.macro.mod("hehe", ({"name": ""}))')
|
|
73
|
+
|
|
74
|
+
with self.raises(s_exc.BadArg):
|
|
75
|
+
await core.nodes('$lib.macro.mod("", ({"name": "foobar"}))')
|
|
76
|
+
|
|
56
77
|
with self.raises(s_exc.AuthDeny):
|
|
57
78
|
await core.nodes('$lib.macro.set(hehe, ${ inet:ipv6 })', opts=asvisi)
|
|
58
79
|
|
|
@@ -118,6 +139,14 @@ class MacroTest(s_test.SynTest):
|
|
|
118
139
|
msgs = await core.stormlist('macro.del print', opts={'readonly': True})
|
|
119
140
|
self.stormIsInErr('not marked readonly safe', msgs)
|
|
120
141
|
|
|
142
|
+
msgs = await core.stormlist('macro.set blorpblorp "+#foo"', opts=asvisi)
|
|
143
|
+
self.stormHasNoWarnErr(msgs)
|
|
144
|
+
|
|
145
|
+
await core.auth.delUser(visi.iden)
|
|
146
|
+
msgs = await core.stormlist('macro.list')
|
|
147
|
+
self.stormIsInPrint("User not found", msgs)
|
|
148
|
+
self.stormIsInPrint(visi.iden, msgs)
|
|
149
|
+
|
|
121
150
|
async def test_stormlib_macro_vars(self):
|
|
122
151
|
|
|
123
152
|
async with self.getTestCore() as core:
|
|
@@ -319,3 +348,68 @@ class MacroTest(s_test.SynTest):
|
|
|
319
348
|
await visi.addRule((True, ('storm', 'macro', 'admin')))
|
|
320
349
|
msgs = await core.stormlist('macro.del asdf', opts={'user': visi.iden})
|
|
321
350
|
self.stormHasNoWarnErr(msgs)
|
|
351
|
+
|
|
352
|
+
async def test_stormlib_behold_macro(self):
|
|
353
|
+
self.skipIfNexusReplay()
|
|
354
|
+
async with self.getTestCore() as core:
|
|
355
|
+
host, port = await core.addHttpsPort(0, host='127.0.0.1')
|
|
356
|
+
|
|
357
|
+
visi = await core.auth.addUser('visi')
|
|
358
|
+
await visi.setPasswd('secret')
|
|
359
|
+
await visi.setAdmin(True)
|
|
360
|
+
|
|
361
|
+
async with self.getHttpSess() as sess:
|
|
362
|
+
async with sess.post(f'https://localhost:{port}/api/v1/login', json={'user': 'visi', 'passwd': 'secret'}) as resp:
|
|
363
|
+
retn = await resp.json()
|
|
364
|
+
self.eq('ok', retn.get('status'))
|
|
365
|
+
self.eq('visi', retn['result']['name'])
|
|
366
|
+
|
|
367
|
+
async with sess.ws_connect(f'wss://localhost:{port}/api/v1/behold') as sock:
|
|
368
|
+
await sock.send_json({'type': 'call:init'})
|
|
369
|
+
mesg = await sock.receive_json()
|
|
370
|
+
self.eq(mesg['type'], 'init')
|
|
371
|
+
|
|
372
|
+
await core.callStorm('''
|
|
373
|
+
$lib.macro.set('foobar', ${ file:bytes | [+#neato] })
|
|
374
|
+
$lib.macro.set('foobar', ${ inet:ipv4 | [+#burrito] })
|
|
375
|
+
$lib.macro.mod('foobar', ({'name': 'bizbaz'}))
|
|
376
|
+
$lib.macro.grant('bizbaz', users, $visi, 3)
|
|
377
|
+
$lib.macro.del('bizbaz')
|
|
378
|
+
''', opts={'vars': {'visi': visi.iden}})
|
|
379
|
+
|
|
380
|
+
addmesg = await sock.receive_json()
|
|
381
|
+
self.eq('storm:macro:add', addmesg['data']['event'])
|
|
382
|
+
macro = addmesg['data']['info']['macro']
|
|
383
|
+
self.eq(macro['name'], 'foobar')
|
|
384
|
+
self.eq(macro['storm'], 'file:bytes | [+#neato]')
|
|
385
|
+
self.ne(visi.iden, macro['user'])
|
|
386
|
+
self.ne(visi.iden, macro['creator'])
|
|
387
|
+
self.nn(macro['iden'])
|
|
388
|
+
|
|
389
|
+
setmesg = await sock.receive_json()
|
|
390
|
+
self.eq('storm:macro:mod', setmesg['data']['event'])
|
|
391
|
+
event = setmesg['data']['info']
|
|
392
|
+
self.nn(event['macro'])
|
|
393
|
+
self.eq(event['info']['storm'], 'inet:ipv4 | [+#burrito]')
|
|
394
|
+
self.nn(event['info']['updated'])
|
|
395
|
+
|
|
396
|
+
modmesg = await sock.receive_json()
|
|
397
|
+
self.eq('storm:macro:mod', modmesg['data']['event'])
|
|
398
|
+
event = modmesg['data']['info']
|
|
399
|
+
self.nn(event['macro'])
|
|
400
|
+
self.eq(event['info']['name'], 'bizbaz')
|
|
401
|
+
self.nn(event['info']['updated'])
|
|
402
|
+
|
|
403
|
+
grantmesg = await sock.receive_json()
|
|
404
|
+
self.eq('storm:macro:set:perm', grantmesg['data']['event'])
|
|
405
|
+
event = grantmesg['data']['info']
|
|
406
|
+
self.nn(event['macro'])
|
|
407
|
+
self.eq(event['info']['level'], 3)
|
|
408
|
+
self.eq(event['info']['scope'], 'users')
|
|
409
|
+
self.eq(event['info']['iden'], visi.iden)
|
|
410
|
+
|
|
411
|
+
delmesg = await sock.receive_json()
|
|
412
|
+
self.eq('storm:macro:del', delmesg['data']['event'])
|
|
413
|
+
event = delmesg['data']['info']
|
|
414
|
+
self.nn(event['iden'])
|
|
415
|
+
self.eq(event['name'], 'bizbaz')
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import synapse.exc as s_exc
|
|
2
|
+
import synapse.lib.stormtypes as s_stormtypes
|
|
3
|
+
|
|
4
|
+
import synapse.tests.utils as s_test
|
|
5
|
+
|
|
6
|
+
class StormlibSpooledTest(s_test.SynTest):
|
|
7
|
+
async def test_lib_spooled_set(self):
|
|
8
|
+
async with self.getTestCore() as core:
|
|
9
|
+
await core.nodes('[inet:ipv4=1.2.3.4 :asn=20]')
|
|
10
|
+
await core.nodes('[inet:ipv4=5.6.7.8 :asn=30]')
|
|
11
|
+
|
|
12
|
+
q = '''
|
|
13
|
+
$set = $lib.spooled.set()
|
|
14
|
+
$set.add(1, 2, 3, 4)
|
|
15
|
+
return($set)
|
|
16
|
+
'''
|
|
17
|
+
valu = await core.callStorm(q)
|
|
18
|
+
self.eq({'1', '2', '3', '4'}, valu)
|
|
19
|
+
|
|
20
|
+
q = '''
|
|
21
|
+
$set = $lib.spooled.set()
|
|
22
|
+
$set.adds($lib.list(1, 2, 3, 4))
|
|
23
|
+
return($set)
|
|
24
|
+
'''
|
|
25
|
+
valu = await core.callStorm(q)
|
|
26
|
+
self.eq({'1', '2', '3', '4'}, valu)
|
|
27
|
+
|
|
28
|
+
q = '''
|
|
29
|
+
$set = $lib.spooled.set()
|
|
30
|
+
inet:ipv4 $set.add(:asn)
|
|
31
|
+
$set.rems((:asn,:asn))
|
|
32
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$set.list() ]
|
|
33
|
+
'''
|
|
34
|
+
nodes = await core.nodes(q)
|
|
35
|
+
self.len(1, nodes)
|
|
36
|
+
self.eq(nodes[0].get('data'), ())
|
|
37
|
+
|
|
38
|
+
q = '''
|
|
39
|
+
$set = $lib.spooled.set()
|
|
40
|
+
$set.add($foo)
|
|
41
|
+
$set.add($bar)
|
|
42
|
+
$set.add($biz)
|
|
43
|
+
return(($set.has($foo), $set.has(lolnop)))
|
|
44
|
+
'''
|
|
45
|
+
valu = await core.callStorm(q, opts={'vars': {'foo': b'foo', 'bar': b'bar', 'biz': b'biz'}})
|
|
46
|
+
self.eq(True, valu[0])
|
|
47
|
+
self.eq(False, valu[1])
|
|
48
|
+
|
|
49
|
+
q = '''
|
|
50
|
+
$set = $lib.spooled.set()
|
|
51
|
+
$set.adds(('foo', 'bar', 'baz', 'biz', 'biz', 'biz', 'beep', 'boop'))
|
|
52
|
+
return($set.size())
|
|
53
|
+
'''
|
|
54
|
+
valu = await core.callStorm(q)
|
|
55
|
+
self.eq(6, valu)
|
|
56
|
+
|
|
57
|
+
q = '''
|
|
58
|
+
$set = $lib.spooled.set()
|
|
59
|
+
$set.adds(('foo', 'bar', 'baz', 'biz', 'biz', 'biz', 'beep', 'boop'))
|
|
60
|
+
|
|
61
|
+
$set.rems(('baz', 'beep', 'bar'))
|
|
62
|
+
return($set)
|
|
63
|
+
|
|
64
|
+
'''
|
|
65
|
+
valu = await core.callStorm(q)
|
|
66
|
+
self.eq({'foo', 'boop', 'biz'}, valu)
|
|
67
|
+
|
|
68
|
+
q = '''
|
|
69
|
+
$set = $lib.spooled.set(1, 2, 3, 4 ,5)
|
|
70
|
+
$set.add(1, 2, 3, 4)
|
|
71
|
+
return($set.list())
|
|
72
|
+
'''
|
|
73
|
+
valu = await core.callStorm(q)
|
|
74
|
+
self.isinstance(valu, tuple)
|
|
75
|
+
self.len(5, valu)
|
|
76
|
+
self.isin('1', valu)
|
|
77
|
+
self.isin('2', valu)
|
|
78
|
+
self.isin('3', valu)
|
|
79
|
+
self.isin('4', valu)
|
|
80
|
+
self.isin('5', valu)
|
|
81
|
+
|
|
82
|
+
q = '''
|
|
83
|
+
$set = $lib.spooled.set()
|
|
84
|
+
$set.add($lib.true)
|
|
85
|
+
$set.add($lib.false)
|
|
86
|
+
$set.add($lib.true)
|
|
87
|
+
$set.add($lib.false)
|
|
88
|
+
$set.add('more stuff')
|
|
89
|
+
|
|
90
|
+
$dict = ({
|
|
91
|
+
"foo": "bar",
|
|
92
|
+
"biz": "baz",
|
|
93
|
+
})
|
|
94
|
+
$set.adds($dict)
|
|
95
|
+
return($set)
|
|
96
|
+
'''
|
|
97
|
+
valu = await core.callStorm(q)
|
|
98
|
+
self.len(5, valu)
|
|
99
|
+
self.isin(False, valu)
|
|
100
|
+
self.isin(True, valu)
|
|
101
|
+
self.isin('more stuff', valu)
|
|
102
|
+
self.isin(('biz', 'baz'), valu)
|
|
103
|
+
self.isin(('foo', 'bar'), valu)
|
|
104
|
+
|
|
105
|
+
q = '''
|
|
106
|
+
$set = $lib.spooled.set()
|
|
107
|
+
$set.adds($items)
|
|
108
|
+
for $x in $set {
|
|
109
|
+
$lib.print(`{$x} exists in the set`)
|
|
110
|
+
}
|
|
111
|
+
return()
|
|
112
|
+
'''
|
|
113
|
+
msgs = await core.stormlist(q, opts={'vars': {'items': [True, 'neato', False, 9001]}})
|
|
114
|
+
self.len(7, msgs)
|
|
115
|
+
self.stormIsInPrint('false exists in the set', msgs)
|
|
116
|
+
self.stormIsInPrint('true exists in the set', msgs)
|
|
117
|
+
self.stormIsInPrint('neato exists in the set', msgs)
|
|
118
|
+
self.stormIsInPrint('9001 exists in the set', msgs)
|
|
119
|
+
|
|
120
|
+
q = '''
|
|
121
|
+
$set = $lib.spooled.set(neato, neato, neato, neato)
|
|
122
|
+
$lib.print(`The set is {$set}`)
|
|
123
|
+
'''
|
|
124
|
+
msgs = await core.stormlist(q, opts={'vars': {'items': [True, 'neato', False, 9001]}})
|
|
125
|
+
self.stormIsInPrint("The set is {'neato'}", msgs)
|
|
126
|
+
|
|
127
|
+
# force a fallback
|
|
128
|
+
q = '''
|
|
129
|
+
$set = $lib.spooled.set()
|
|
130
|
+
$set.adds($lib.range(1500))
|
|
131
|
+
return($set.size())
|
|
132
|
+
'''
|
|
133
|
+
valu = await core.callStorm(q)
|
|
134
|
+
self.eq(1500, valu)
|
|
135
|
+
|
|
136
|
+
# sad paths
|
|
137
|
+
# too complex
|
|
138
|
+
q = '''
|
|
139
|
+
$set = $lib.spooled.set()
|
|
140
|
+
$set.add($stormnode)
|
|
141
|
+
return($set)
|
|
142
|
+
'''
|
|
143
|
+
stormnode = s_stormtypes.Node(nodes[0])
|
|
144
|
+
await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q, {'vars': {'stormnode': stormnode}}))
|
|
145
|
+
|
|
146
|
+
# mutable failures
|
|
147
|
+
q = '''
|
|
148
|
+
$set = $lib.spooled.set()
|
|
149
|
+
$set.add(({'neato': 'burrito'}))
|
|
150
|
+
return($set)
|
|
151
|
+
'''
|
|
152
|
+
await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q))
|
|
153
|
+
|
|
154
|
+
q = '''
|
|
155
|
+
$set = $lib.spooled.set()
|
|
156
|
+
$dict = ({'neato': 'burrito'})
|
|
157
|
+
$set.adds(($dict, $dict))
|
|
158
|
+
return($set)
|
|
159
|
+
'''
|
|
160
|
+
await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q))
|
|
161
|
+
|
|
162
|
+
q = '''
|
|
163
|
+
$set = $lib.spooled.set()
|
|
164
|
+
$form = $lib.model.form('inet:ipv4')
|
|
165
|
+
$set.adds(($stormnode, $form, $form))
|
|
166
|
+
return($set)
|
|
167
|
+
'''
|
|
168
|
+
# it'll blow up on the first
|
|
169
|
+
await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q, {'vars': {'stormnode': stormnode}}))
|
|
170
|
+
|
|
171
|
+
q = '''
|
|
172
|
+
$dict = ({'foo': 'bar'})
|
|
173
|
+
$set = $lib.spooled.set($dict)
|
|
174
|
+
return($set)
|
|
175
|
+
'''
|
|
176
|
+
await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q))
|
|
177
|
+
|
|
178
|
+
# type not msgpack-able
|
|
179
|
+
q = '''
|
|
180
|
+
$set = $lib.spooled.set()
|
|
181
|
+
$set.add($lib.model.form("inet:ipv4"))
|
|
182
|
+
return($set)
|
|
183
|
+
'''
|
|
184
|
+
await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q))
|
|
185
|
+
|
|
186
|
+
q = '''
|
|
187
|
+
$set = $lib.spooled.set($stormnode)
|
|
188
|
+
return($set)
|
|
189
|
+
'''
|
|
190
|
+
await self.asyncraises(s_exc.StormRuntimeError, core.callStorm(q, {'vars': {'stormnode': stormnode}}))
|
|
@@ -20,7 +20,6 @@ import synapse.lib.storm as s_storm
|
|
|
20
20
|
import synapse.lib.hashset as s_hashset
|
|
21
21
|
import synapse.lib.httpapi as s_httpapi
|
|
22
22
|
import synapse.lib.modelrev as s_modelrev
|
|
23
|
-
import synapse.lib.provenance as s_provenance
|
|
24
23
|
import synapse.lib.stormtypes as s_stormtypes
|
|
25
24
|
|
|
26
25
|
import synapse.tests.utils as s_test
|
|
@@ -1344,34 +1343,34 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1344
1343
|
n2 = s_common.guid()
|
|
1345
1344
|
n3 = s_common.guid()
|
|
1346
1345
|
|
|
1347
|
-
nodes = await core.nodes('[
|
|
1346
|
+
nodes = await core.nodes('[tel:mob:telem="*" :data=$data]', opts={'vars': {'data': ghstr}})
|
|
1348
1347
|
self.len(1, nodes)
|
|
1349
1348
|
node1 = nodes[0]
|
|
1350
1349
|
|
|
1351
|
-
nodes = await core.nodes('[
|
|
1350
|
+
nodes = await core.nodes('[tel:mob:telem="*" :data=$data]', opts={'vars': {'data': mstr}})
|
|
1352
1351
|
self.len(1, nodes)
|
|
1353
1352
|
node2 = nodes[0]
|
|
1354
|
-
q = '''
|
|
1353
|
+
q = '''tel:mob:telem=$n1 $gzthing = :data
|
|
1355
1354
|
$foo = $lib.base64.decode($gzthing).gunzip()
|
|
1356
1355
|
$lib.print($foo)
|
|
1357
|
-
[(
|
|
1356
|
+
[( tel:mob:telem=$n2 :data=$foo.decode() )]'''
|
|
1358
1357
|
|
|
1359
1358
|
msgs = await core.stormlist(q, opts={'vars': {'n1': node1.ndef[1], 'n2': n2}})
|
|
1360
1359
|
self.stormHasNoWarnErr(msgs)
|
|
1361
1360
|
self.stormIsInPrint('ohhai', msgs)
|
|
1362
1361
|
|
|
1363
1362
|
# make sure we gunzip correctly
|
|
1364
|
-
nodes = await core.nodes('
|
|
1363
|
+
nodes = await core.nodes('tel:mob:telem=$valu', opts={'vars': {'valu': n2}})
|
|
1365
1364
|
self.len(1, nodes)
|
|
1366
1365
|
self.eq(hstr, nodes[0].get('data'))
|
|
1367
1366
|
|
|
1368
|
-
text = f'''
|
|
1369
|
-
[(
|
|
1367
|
+
text = f'''tel:mob:telem=$n2 $bar = :data
|
|
1368
|
+
[( tel:mob:telem=$n3 :data=$lib.base64.encode($bar.encode().gzip()) )]'''
|
|
1370
1369
|
msgs = await core.stormlist(text, opts={'vars': {'n2': node2.ndef[1], 'n3': n3}})
|
|
1371
1370
|
self.stormHasNoWarnErr(msgs)
|
|
1372
1371
|
|
|
1373
1372
|
# make sure we gzip correctly
|
|
1374
|
-
nodes = await core.nodes('
|
|
1373
|
+
nodes = await core.nodes('tel:mob:telem=$valu', opts={'vars': {'valu': n3}})
|
|
1375
1374
|
self.len(1, nodes)
|
|
1376
1375
|
self.eq(mstr.encode(), gzip.decompress(base64.urlsafe_b64decode(nodes[0].props['data'])))
|
|
1377
1376
|
|
|
@@ -1384,30 +1383,30 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1384
1383
|
n2 = s_common.guid()
|
|
1385
1384
|
n3 = s_common.guid()
|
|
1386
1385
|
|
|
1387
|
-
nodes = await core.nodes('[
|
|
1386
|
+
nodes = await core.nodes('[tel:mob:telem="*" :data=$data]', opts={'vars': {'data': ghstr}})
|
|
1388
1387
|
self.len(1, nodes)
|
|
1389
1388
|
node1 = nodes[0]
|
|
1390
|
-
nodes = await core.nodes('[
|
|
1389
|
+
nodes = await core.nodes('[tel:mob:telem="*" :data=$data]', opts={'vars': {'data': mstr}})
|
|
1391
1390
|
self.len(1, nodes)
|
|
1392
1391
|
node2 = nodes[0]
|
|
1393
1392
|
|
|
1394
|
-
q = '''
|
|
1393
|
+
q = '''tel:mob:telem=$valu $bzthing = :data $foo = $lib.base64.decode($bzthing).bunzip()
|
|
1395
1394
|
$lib.print($foo)
|
|
1396
|
-
[(
|
|
1395
|
+
[( tel:mob:telem=$n2 :data=$foo.decode() )] -tel:mob:telem=$valu'''
|
|
1397
1396
|
msgs = await core.stormlist(q, opts={'vars': {'valu': node1.ndef[1], 'n2': n2}})
|
|
1398
1397
|
self.stormHasNoWarnErr(msgs)
|
|
1399
1398
|
self.stormIsInPrint('ohhai', msgs)
|
|
1400
1399
|
|
|
1401
1400
|
# make sure we bunzip correctly
|
|
1402
1401
|
opts = {'vars': {'iden': n2}}
|
|
1403
|
-
nodes = await core.nodes('
|
|
1402
|
+
nodes = await core.nodes('tel:mob:telem=$iden', opts=opts)
|
|
1404
1403
|
self.len(1, nodes)
|
|
1405
1404
|
node = nodes[0]
|
|
1406
1405
|
self.eq(node.get('data'), hstr)
|
|
1407
1406
|
|
|
1408
1407
|
# bzip
|
|
1409
|
-
q = '''
|
|
1410
|
-
[(
|
|
1408
|
+
q = '''tel:mob:telem=$valu $bar = :data
|
|
1409
|
+
[( tel:mob:telem=$n3 :data=$lib.base64.encode($bar.encode().bzip()) )] -tel:mob:telem=$valu'''
|
|
1411
1410
|
nodes = await core.nodes(q, opts={'vars': {'valu': node2.ndef[1], 'n3': n3}})
|
|
1412
1411
|
self.len(1, nodes)
|
|
1413
1412
|
node = nodes[0]
|
|
@@ -1421,13 +1420,13 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1421
1420
|
valu = s_common.guid()
|
|
1422
1421
|
n2 = s_common.guid()
|
|
1423
1422
|
|
|
1424
|
-
nodes = await core.nodes('[
|
|
1423
|
+
nodes = await core.nodes('[tel:mob:telem=$valu :data=$data]', opts={'vars': {'valu': valu, 'data': ghstr}})
|
|
1425
1424
|
self.len(1, nodes)
|
|
1426
1425
|
node1 = nodes[0]
|
|
1427
1426
|
self.eq(node1.get('data'), ghstr)
|
|
1428
1427
|
|
|
1429
|
-
q = '''
|
|
1430
|
-
-
|
|
1428
|
+
q = '''tel:mob:telem=$valu $jzthing=:data $foo=$jzthing.encode().json() [(tel:mob:telem=$n2 :data=$foo)]
|
|
1429
|
+
-tel:mob:telem=$valu'''
|
|
1431
1430
|
nodes = await core.nodes(q, opts={'vars': {'valu': valu, 'n2': n2}})
|
|
1432
1431
|
self.len(1, nodes)
|
|
1433
1432
|
node2 = nodes[0]
|
|
@@ -1721,7 +1720,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1721
1720
|
q = '''
|
|
1722
1721
|
$set = $lib.set()
|
|
1723
1722
|
inet:ipv4 $set.add(:asn)
|
|
1724
|
-
[
|
|
1723
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$set.list() ]
|
|
1725
1724
|
'''
|
|
1726
1725
|
nodes = await core.nodes(q)
|
|
1727
1726
|
self.len(1, nodes)
|
|
@@ -1730,7 +1729,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1730
1729
|
q = '''
|
|
1731
1730
|
$set = $lib.set()
|
|
1732
1731
|
inet:ipv4 $set.adds((:asn,:asn))
|
|
1733
|
-
[
|
|
1732
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$set.list() ]
|
|
1734
1733
|
'''
|
|
1735
1734
|
nodes = await core.nodes(q)
|
|
1736
1735
|
self.len(1, nodes)
|
|
@@ -1740,7 +1739,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1740
1739
|
$set = $lib.set()
|
|
1741
1740
|
inet:ipv4 $set.adds((:asn,:asn))
|
|
1742
1741
|
{ +:asn=20 $set.rem(:asn) }
|
|
1743
|
-
[
|
|
1742
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$set.list() ]
|
|
1744
1743
|
'''
|
|
1745
1744
|
nodes = await core.nodes(q)
|
|
1746
1745
|
self.len(1, nodes)
|
|
@@ -1750,7 +1749,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1750
1749
|
$set = $lib.set()
|
|
1751
1750
|
inet:ipv4 $set.add(:asn)
|
|
1752
1751
|
$set.rems((:asn,:asn))
|
|
1753
|
-
[
|
|
1752
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$set.list() ]
|
|
1754
1753
|
'''
|
|
1755
1754
|
nodes = await core.nodes(q)
|
|
1756
1755
|
self.len(1, nodes)
|
|
@@ -2152,7 +2151,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2152
2151
|
q = '''
|
|
2153
2152
|
inet:fqdn=vertex.link -> inet:dns:a -> inet:ipv4
|
|
2154
2153
|
$idens = $path.idens()
|
|
2155
|
-
[
|
|
2154
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$idens ]
|
|
2156
2155
|
'''
|
|
2157
2156
|
|
|
2158
2157
|
idens = (
|
|
@@ -2700,6 +2699,17 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2700
2699
|
await core.addUserRule(user, (True, ('storm', 'lib', 'telepath', 'open', 'cell')))
|
|
2701
2700
|
self.len(2, await core.callStorm('return ( $lib.telepath.open($url).ipv4s() )', opts=opts))
|
|
2702
2701
|
|
|
2702
|
+
# SynErr exceptions are allowed through. They can be caught by storm.
|
|
2703
|
+
with self.raises(s_exc.BadUrl):
|
|
2704
|
+
await core.callStorm('$prox=$lib.telepath.open("weeeeeeeeeeeeee")')
|
|
2705
|
+
|
|
2706
|
+
# Python exceptions are caught and raised as StormRuntimeError exceptions.
|
|
2707
|
+
with self.raises(s_exc.StormRuntimeError) as cm:
|
|
2708
|
+
await core.callStorm('$prox=$lib.telepath.open("tcp://0.0.0.0:60000")')
|
|
2709
|
+
emsg = cm.exception.get('mesg')
|
|
2710
|
+
self.isin('Failed to connect to Telepath service: "tcp://0.0.0.0:60000" error:', emsg)
|
|
2711
|
+
self.isin('Connect call failed', emsg)
|
|
2712
|
+
|
|
2703
2713
|
async def test_storm_lib_queue(self):
|
|
2704
2714
|
|
|
2705
2715
|
async with self.getTestCore() as core:
|
|
@@ -4475,7 +4485,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4475
4485
|
|
|
4476
4486
|
async with self.getTestCore() as core:
|
|
4477
4487
|
|
|
4478
|
-
cdef = await core.callStorm('return($lib.cron.add(query="{[
|
|
4488
|
+
cdef = await core.callStorm('return($lib.cron.add(query="{[tel:mob:telem=*]}", hourly=30).pack())')
|
|
4479
4489
|
self.eq('', cdef.get('doc'))
|
|
4480
4490
|
self.eq('', cdef.get('name'))
|
|
4481
4491
|
|
|
@@ -4491,7 +4501,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4491
4501
|
with self.raises(s_exc.BadArg):
|
|
4492
4502
|
await core.callStorm('return($lib.cron.get($iden).set(hehe, haha))', opts=opts)
|
|
4493
4503
|
|
|
4494
|
-
mesgs = await core.stormlist('cron.add --hour +1 {[
|
|
4504
|
+
mesgs = await core.stormlist('cron.add --hour +1 {[tel:mob:telem=*]} --name myname --doc mydoc')
|
|
4495
4505
|
for mesg in mesgs:
|
|
4496
4506
|
if mesg[0] == 'print':
|
|
4497
4507
|
iden0 = mesg[1]['mesg'].split(' ')[-1]
|
|
@@ -4512,7 +4522,6 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4512
4522
|
|
|
4513
4523
|
MONO_DELT = 1543827303.0
|
|
4514
4524
|
unixtime = datetime.datetime(year=2018, month=12, day=5, hour=7, minute=0, tzinfo=tz.utc).timestamp()
|
|
4515
|
-
s_provenance.reset()
|
|
4516
4525
|
|
|
4517
4526
|
def timetime():
|
|
4518
4527
|
return unixtime
|
|
@@ -4597,7 +4606,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4597
4606
|
nextlayroffs = await layr.getEditOffs() + 1
|
|
4598
4607
|
|
|
4599
4608
|
# Start simple: add a cron job that creates a node every minute
|
|
4600
|
-
q = "cron.add --minute +1 {[
|
|
4609
|
+
q = "cron.add --minute +1 {[meta:note='*' :type=m1]}"
|
|
4601
4610
|
mesgs = await core.stormlist(q)
|
|
4602
4611
|
self.stormIsInPrint('Created cron job', mesgs)
|
|
4603
4612
|
for mesg in mesgs:
|
|
@@ -4639,24 +4648,24 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4639
4648
|
|
|
4640
4649
|
# Make sure it ran
|
|
4641
4650
|
await layr.waitEditOffs(nextlayroffs, timeout=5)
|
|
4642
|
-
self.eq(1, await prox.count('
|
|
4651
|
+
self.eq(1, await prox.count('meta:note:type=m1'))
|
|
4643
4652
|
|
|
4644
|
-
q = "cron.mod $guid { [
|
|
4653
|
+
q = "cron.mod $guid { [meta:note='*' :type=m2] }"
|
|
4645
4654
|
mesgs = await core.stormlist(q, opts={'vars': {'guid': guid[:6]}})
|
|
4646
4655
|
self.stormIsInPrint(f'Modified cron job: {guid}', mesgs)
|
|
4647
4656
|
|
|
4648
|
-
q = "cron.mod xxx { [
|
|
4657
|
+
q = "cron.mod xxx { [meta:note='*' :type=m2] }"
|
|
4649
4658
|
mesgs = await core.stormlist(q)
|
|
4650
4659
|
self.stormIsInErr('does not match', mesgs)
|
|
4651
4660
|
|
|
4652
4661
|
# Make sure the old one didn't run and the new query ran
|
|
4653
4662
|
unixtime += 60
|
|
4654
4663
|
await asyncio.sleep(0)
|
|
4655
|
-
self.eq(1, await prox.count('
|
|
4664
|
+
self.eq(1, await prox.count('meta:note:type=m1'))
|
|
4656
4665
|
# UNG WTF
|
|
4657
4666
|
await asyncio.sleep(0)
|
|
4658
4667
|
await asyncio.sleep(0)
|
|
4659
|
-
self.eq(1, await prox.count('
|
|
4668
|
+
self.eq(1, await prox.count('meta:note:type=m2'))
|
|
4660
4669
|
|
|
4661
4670
|
# Delete the job
|
|
4662
4671
|
q = f"cron.del {guid}"
|
|
@@ -4669,8 +4678,8 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4669
4678
|
|
|
4670
4679
|
# Make sure deleted job didn't run
|
|
4671
4680
|
unixtime += 60
|
|
4672
|
-
self.eq(1, await prox.count('
|
|
4673
|
-
self.eq(1, await prox.count('
|
|
4681
|
+
self.eq(1, await prox.count('meta:note:type=m1'))
|
|
4682
|
+
self.eq(1, await prox.count('meta:note:type=m2'))
|
|
4674
4683
|
|
|
4675
4684
|
# Test fixed minute, i.e. every hour at 17 past
|
|
4676
4685
|
unixtime = datetime.datetime(year=2018, month=12, day=5, hour=7, minute=10,
|
|
@@ -4846,6 +4855,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4846
4855
|
|
|
4847
4856
|
self.stormIsInPrint('last result: finished successfully with 0 nodes', mesgs)
|
|
4848
4857
|
self.stormIsInPrint('entries: <None>', mesgs)
|
|
4858
|
+
self.stormIsInPrint('pool: false', mesgs)
|
|
4849
4859
|
|
|
4850
4860
|
# Test 'stat' command
|
|
4851
4861
|
mesgs = await core.stormlist('cron.stat xxx')
|
|
@@ -4919,7 +4929,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4919
4929
|
self.stormIsInErr('data.iden must match pattern', msgs)
|
|
4920
4930
|
|
|
4921
4931
|
opts = {'vars': {'iden': 'cd263bd133a5dafa1e1c5e9a01d9d486'}}
|
|
4922
|
-
q = "cron.add --iden $iden --day +1 --minute 14 {[test:guid=$lib.guid()]}"
|
|
4932
|
+
q = "cron.add --pool --iden $iden --day +1 --minute 14 {[test:guid=$lib.guid()]}"
|
|
4923
4933
|
msgs = await core.stormlist(q, opts=opts)
|
|
4924
4934
|
self.stormIsInPrint('Created cron job: cd263bd133a5dafa1e1c5e9a01d9d486', msgs)
|
|
4925
4935
|
|
|
@@ -6465,6 +6475,10 @@ words\tword\twrd'''
|
|
|
6465
6475
|
self.eq(merge['creator'], core.auth.rootuser.iden)
|
|
6466
6476
|
self.none(merge.get('updated'))
|
|
6467
6477
|
|
|
6478
|
+
merging = 'return($lib.view.get().getMergingViews()) '
|
|
6479
|
+
|
|
6480
|
+
self.eq([fork00], await core.callStorm(merging))
|
|
6481
|
+
|
|
6468
6482
|
with self.raises(s_exc.AuthDeny):
|
|
6469
6483
|
core.getView(fork00).reqValidVoter(root.iden)
|
|
6470
6484
|
|
|
@@ -6540,8 +6554,13 @@ words\tword\twrd'''
|
|
|
6540
6554
|
self.none(core.getView(fork00))
|
|
6541
6555
|
nodes = await core.nodes('inet:fqdn')
|
|
6542
6556
|
self.len(2, nodes)
|
|
6557
|
+
|
|
6558
|
+
# previously successful merges
|
|
6543
6559
|
self.len(1, await core.callStorm('$list = ([]) for $merge in $lib.view.get().getMerges() { $list.append($merge) } fini { return($list) }'))
|
|
6544
6560
|
|
|
6561
|
+
# current open merge requests
|
|
6562
|
+
self.eq([], await core.callStorm(merging))
|
|
6563
|
+
|
|
6545
6564
|
# test out the delMergeRequest logic / cleanup
|
|
6546
6565
|
forkdef = await core.getView().fork()
|
|
6547
6566
|
|
|
@@ -6549,6 +6568,7 @@ words\tword\twrd'''
|
|
|
6549
6568
|
|
|
6550
6569
|
opts = {'view': fork.iden}
|
|
6551
6570
|
self.nn(await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts))
|
|
6571
|
+
self.eq([fork.iden], await core.callStorm(merging))
|
|
6552
6572
|
|
|
6553
6573
|
# confirm that you may not re-parent to a view with a merge request
|
|
6554
6574
|
layr = await core.addLayer()
|
|
@@ -6564,6 +6584,8 @@ words\tword\twrd'''
|
|
|
6564
6584
|
self.nn(await core.callStorm('return($lib.view.get().delMergeRequest())', opts=opts))
|
|
6565
6585
|
self.len(0, [vote async for vote in fork.getMergeVotes()])
|
|
6566
6586
|
|
|
6587
|
+
self.eq([], await core.callStorm(merging))
|
|
6588
|
+
|
|
6567
6589
|
# test coverage for beholder progress events...
|
|
6568
6590
|
forkdef = await core.getView().fork()
|
|
6569
6591
|
fork = core.getView(forkdef.get('iden'))
|
|
@@ -6572,10 +6594,12 @@ words\tword\twrd'''
|
|
|
6572
6594
|
await core.stormlist('[ inet:ipv4=1.2.3.0/20 ]', opts=opts)
|
|
6573
6595
|
await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts)
|
|
6574
6596
|
|
|
6597
|
+
self.eq([fork.iden], await core.callStorm(merging))
|
|
6598
|
+
|
|
6575
6599
|
nevents = 8
|
|
6576
6600
|
if s_common.envbool('SYNDEV_NEXUS_REPLAY'):
|
|
6577
6601
|
# view:merge:vote:set fires twice
|
|
6578
|
-
nevents
|
|
6602
|
+
nevents += 1
|
|
6579
6603
|
waiter = core.waiter(nevents, 'cell:beholder')
|
|
6580
6604
|
|
|
6581
6605
|
opts = {'view': fork.iden, 'user': visi.iden}
|
|
@@ -6598,6 +6622,8 @@ words\tword\twrd'''
|
|
|
6598
6622
|
self.eq(msgs[-1][1]['info']['merge']['creator'], core.auth.rootuser.iden)
|
|
6599
6623
|
self.eq(msgs[-1][1]['info']['votes'][0]['user'], visi.iden)
|
|
6600
6624
|
|
|
6625
|
+
self.eq([], await core.callStorm(merging))
|
|
6626
|
+
|
|
6601
6627
|
# test coverage for bad state for merge request
|
|
6602
6628
|
fork00 = await core.getView().fork()
|
|
6603
6629
|
fork01 = await core.getView(fork00['iden']).fork()
|
|
@@ -6606,8 +6632,11 @@ words\tword\twrd'''
|
|
|
6606
6632
|
with self.raises(s_exc.BadState):
|
|
6607
6633
|
await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts)
|
|
6608
6634
|
|
|
6635
|
+
self.eq([], await core.callStorm(merging))
|
|
6636
|
+
|
|
6609
6637
|
await core.delView(fork01['iden'])
|
|
6610
6638
|
await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts)
|
|
6639
|
+
self.eq([fork00['iden']], await core.callStorm(merging))
|
|
6611
6640
|
|
|
6612
6641
|
core.getView().layers[0].readonly = True
|
|
6613
6642
|
with self.raises(s_exc.BadState):
|
|
@@ -6626,6 +6655,8 @@ words\tword\twrd'''
|
|
|
6626
6655
|
await core.stormlist('[ inet:ipv4=5.5.5.5 ]', opts=opts)
|
|
6627
6656
|
await core.callStorm('return($lib.view.get().setMergeRequest())', opts=opts)
|
|
6628
6657
|
|
|
6658
|
+
self.eq(set([fork.iden, fork00['iden']]), set(await core.callStorm(merging)))
|
|
6659
|
+
|
|
6629
6660
|
# hamstring the runViewMerge method on the new view
|
|
6630
6661
|
async def fake():
|
|
6631
6662
|
return
|
|
@@ -6660,3 +6691,6 @@ words\tword\twrd'''
|
|
|
6660
6691
|
|
|
6661
6692
|
msgs = await core.stormlist('$lib.view.get().set(quorum, $lib.null)')
|
|
6662
6693
|
self.stormHasNoWarnErr(msgs)
|
|
6694
|
+
|
|
6695
|
+
with self.raises(s_exc.BadState):
|
|
6696
|
+
await core.callStorm(merging)
|