synapse 2.166.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/cortex.py +31 -1
- synapse/exc.py +1 -0
- synapse/lib/aha.py +2 -0
- synapse/lib/base.py +11 -4
- synapse/lib/cell.py +11 -2
- synapse/lib/hive.py +11 -0
- synapse/lib/node.py +4 -2
- synapse/lib/schemas.py +1 -1
- synapse/lib/stormlib/aha.py +366 -16
- synapse/lib/stormlib/macro.py +11 -18
- synapse/lib/stormlib/stix.py +1 -1
- synapse/lib/stormtypes.py +18 -2
- synapse/lib/types.py +2 -0
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +4 -3
- synapse/models/base.py +8 -0
- synapse/models/files.py +3 -0
- synapse/telepath.py +1 -0
- synapse/tests/files/stormpkg/dotstorm/dotstorm.yaml +3 -0
- synapse/tests/test_cortex.py +39 -2
- synapse/tests/test_lib_aha.py +1 -2
- 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 +3 -3
- synapse/tests/test_lib_stormlib_aha.py +196 -0
- synapse/tests/test_lib_stormlib_compression.py +12 -12
- synapse/tests/test_lib_stormlib_macro.py +94 -0
- synapse/tests/test_lib_stormlib_spooled.py +1 -1
- synapse/tests/test_lib_stormtypes.py +44 -33
- synapse/tests/test_lib_view.py +50 -3
- synapse/tests/test_model_files.py +3 -0
- 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/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-2.166.0.dist-info → synapse-2.167.0.dist-info}/METADATA +3 -3
- {synapse-2.166.0.dist-info → synapse-2.167.0.dist-info}/RECORD +46 -45
- {synapse-2.166.0.dist-info → synapse-2.167.0.dist-info}/LICENSE +0 -0
- {synapse-2.166.0.dist-info → synapse-2.167.0.dist-info}/WHEEL +0 -0
- {synapse-2.166.0.dist-info → synapse-2.167.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import synapse.exc as s_exc
|
|
2
|
+
import synapse.common as s_common
|
|
3
|
+
import synapse.cortex as s_cortex
|
|
4
|
+
|
|
5
|
+
import synapse.lib.cell as s_cell
|
|
6
|
+
|
|
7
|
+
import synapse.tests.utils as s_test
|
|
8
|
+
|
|
9
|
+
class AhaLibTest(s_test.SynTest):
|
|
10
|
+
|
|
11
|
+
async def test_stormlib_aha_basics(self):
|
|
12
|
+
|
|
13
|
+
async with self.getTestAhaProv() as aha:
|
|
14
|
+
|
|
15
|
+
with self.getTestDir() as dirn:
|
|
16
|
+
|
|
17
|
+
dirn00 = s_common.genpath(dirn, 'cell00')
|
|
18
|
+
dirn01 = s_common.genpath(dirn, 'cell01')
|
|
19
|
+
dirn02 = s_common.genpath(dirn, 'cell02')
|
|
20
|
+
dirn03 = s_common.genpath(dirn, 'cell03')
|
|
21
|
+
|
|
22
|
+
replay = s_common.envbool('SYNDEV_NEXUS_REPLAY')
|
|
23
|
+
nevents = 10 if replay else 5
|
|
24
|
+
|
|
25
|
+
waiter = aha.waiter(nevents, 'aha:svcadd')
|
|
26
|
+
|
|
27
|
+
cell00 = await aha.enter_context(self.addSvcToAha(aha, '00.cell', s_cell.Cell, dirn=dirn00))
|
|
28
|
+
cell01 = await aha.enter_context(self.addSvcToAha(aha, '01.cell', s_cell.Cell, dirn=dirn01,
|
|
29
|
+
provinfo={'mirror': 'cell'}))
|
|
30
|
+
cell02 = await aha.enter_context(self.addSvcToAha(aha, 'mysvc', s_cell.Cell, dirn=dirn02))
|
|
31
|
+
core00 = await aha.enter_context(self.addSvcToAha(aha, 'core', s_cortex.Cortex, dirn=dirn03))
|
|
32
|
+
|
|
33
|
+
self.len(nevents, await waiter.wait(timeout=12))
|
|
34
|
+
|
|
35
|
+
svcs = await core00.callStorm('$l=() for $i in $lib.aha.list() { $l.append($i) } fini { return ($l) }')
|
|
36
|
+
self.len(5, svcs)
|
|
37
|
+
|
|
38
|
+
svc = await core00.callStorm('return( $lib.aha.get(core...) )')
|
|
39
|
+
self.eq('core.loop.vertex.link', svc.get('name'))
|
|
40
|
+
svc = await core00.callStorm('return( $lib.aha.get(core.loop.vertex.link))')
|
|
41
|
+
self.eq('core.loop.vertex.link', svc.get('name'))
|
|
42
|
+
svc = await core00.callStorm('return( $lib.aha.get(00.cell...))')
|
|
43
|
+
self.eq('00.cell.loop.vertex.link', svc.get('name'))
|
|
44
|
+
svc = await core00.callStorm('return( $lib.aha.get(cell...))')
|
|
45
|
+
self.eq('cell.loop.vertex.link', svc.get('name'))
|
|
46
|
+
svc = await core00.callStorm('$f=({"mirror": (true)}) return( $lib.aha.get(cell..., filters=$f))')
|
|
47
|
+
self.eq('01.cell.loop.vertex.link', svc.get('name'))
|
|
48
|
+
|
|
49
|
+
# List the aha services available
|
|
50
|
+
msgs = await core00.stormlist('aha.svc.list --nexus')
|
|
51
|
+
self.stormIsInPrint('Nexus', msgs)
|
|
52
|
+
self.stormIsInPrint('00.cell.loop.vertex.link true true true', msgs)
|
|
53
|
+
self.stormIsInPrint('01.cell.loop.vertex.link false true true', msgs)
|
|
54
|
+
self.stormIsInPrint('cell.loop.vertex.link true true true', msgs)
|
|
55
|
+
self.stormIsInPrint('core.loop.vertex.link null true true', msgs)
|
|
56
|
+
self.stormIsInPrint('mysvc.loop.vertex.link null true true', msgs)
|
|
57
|
+
|
|
58
|
+
msgs = await core00.stormlist('aha.svc.list')
|
|
59
|
+
self.stormNotInPrint('Nexus', msgs)
|
|
60
|
+
msgs = await core00.stormlist('aha.svc.stat cell...')
|
|
61
|
+
|
|
62
|
+
# The connections information includes runtime information such as port/host info.
|
|
63
|
+
# Omit checking part of that.
|
|
64
|
+
emsg = '''Resolved cell... to an AHA Service.
|
|
65
|
+
|
|
66
|
+
Name: cell.loop.vertex.link
|
|
67
|
+
Online: true
|
|
68
|
+
Ready: true
|
|
69
|
+
Run iden: ********************************
|
|
70
|
+
Cell iden: ********************************
|
|
71
|
+
Leader: cell
|
|
72
|
+
Connection information:
|
|
73
|
+
ca: loop.vertex.link
|
|
74
|
+
'''
|
|
75
|
+
self.stormIsInPrint(emsg, msgs, deguid=True)
|
|
76
|
+
self.stormIsInPrint(' hostname: 00.cell.loop.vertex.link', msgs)
|
|
77
|
+
self.stormIsInPrint(' scheme: ssl', msgs)
|
|
78
|
+
self.stormIsInPrint(' user: root', msgs)
|
|
79
|
+
|
|
80
|
+
msgs = await core00.stormlist('aha.svc.stat --nexus cell...')
|
|
81
|
+
emsg = '''Resolved cell... to an AHA Service.
|
|
82
|
+
|
|
83
|
+
Name: cell.loop.vertex.link
|
|
84
|
+
Online: true
|
|
85
|
+
Ready: true
|
|
86
|
+
Run iden: ********************************
|
|
87
|
+
Cell iden: ********************************
|
|
88
|
+
Leader: cell
|
|
89
|
+
Nexus: 1
|
|
90
|
+
Connection information:
|
|
91
|
+
ca: loop.vertex.link
|
|
92
|
+
'''
|
|
93
|
+
self.stormIsInPrint(emsg, msgs, deguid=True)
|
|
94
|
+
|
|
95
|
+
msgs = await core00.stormlist('aha.svc.stat --nexus 01.cell...')
|
|
96
|
+
emsg = '''Resolved 01.cell... to an AHA Service.
|
|
97
|
+
|
|
98
|
+
Name: 01.cell.loop.vertex.link
|
|
99
|
+
Online: true
|
|
100
|
+
Ready: true
|
|
101
|
+
Run iden: ********************************
|
|
102
|
+
Cell iden: ********************************
|
|
103
|
+
Leader: cell
|
|
104
|
+
Nexus: 1
|
|
105
|
+
Connection information:
|
|
106
|
+
ca: loop.vertex.link
|
|
107
|
+
'''
|
|
108
|
+
self.stormIsInPrint(emsg, msgs, deguid=True)
|
|
109
|
+
|
|
110
|
+
# Full name works
|
|
111
|
+
msgs = await core00.stormlist('aha.svc.stat 01.cell.loop.vertex.link')
|
|
112
|
+
emsg = '''Resolved 01.cell.loop.vertex.link to an AHA Service.
|
|
113
|
+
|
|
114
|
+
Name: 01.cell.loop.vertex.link
|
|
115
|
+
'''
|
|
116
|
+
self.stormIsInPrint(emsg, msgs, deguid=True)
|
|
117
|
+
|
|
118
|
+
# No item for pool00 yet..
|
|
119
|
+
msgs = await core00.stormlist('aha.svc.stat pool00...')
|
|
120
|
+
self.stormIsInPrint('No service found for: "pool00..."', msgs)
|
|
121
|
+
|
|
122
|
+
msgs = await core00.stormlist('aha.pool.add pool00...')
|
|
123
|
+
self.stormHasNoWarnErr(msgs)
|
|
124
|
+
msgs = await core00.stormlist('aha.pool.svc.add pool00... 00.cell...')
|
|
125
|
+
self.stormHasNoWarnErr(msgs)
|
|
126
|
+
|
|
127
|
+
msgs = await core00.stormlist('aha.svc.stat --nexus pool00...')
|
|
128
|
+
emsg = '''Resolved pool00... to an AHA Pool.
|
|
129
|
+
|
|
130
|
+
The pool currently has 1 members.
|
|
131
|
+
AHA Pool: pool00.loop.vertex.link
|
|
132
|
+
Member: 00.cell.loop.vertex.link'''
|
|
133
|
+
self.stormIsInPrint(emsg, msgs)
|
|
134
|
+
|
|
135
|
+
# Shut down a service
|
|
136
|
+
nevents = 2 if replay else 1
|
|
137
|
+
waiter = aha.waiter(nevents, 'aha:svcdown')
|
|
138
|
+
await cell01.fini()
|
|
139
|
+
self.len(nevents, await waiter.wait(timeout=12))
|
|
140
|
+
|
|
141
|
+
msgs = await core00.stormlist('aha.svc.list')
|
|
142
|
+
self.stormIsInPrint('01.cell.loop.vertex.link false false true', msgs)
|
|
143
|
+
|
|
144
|
+
# Fake a record
|
|
145
|
+
await aha.addAhaSvc('00.newp', info={'urlinfo': {'scheme': 'tcp', 'host': '0.0.0.0', 'port': '3030'}},
|
|
146
|
+
network='loop.vertex.link')
|
|
147
|
+
|
|
148
|
+
msgs = await core00.stormlist('aha.svc.list --nexus')
|
|
149
|
+
emsg = '00.newp.loop.vertex.link null false null 0.0.0.0 3030 ' \
|
|
150
|
+
'Service is not online. Will not attempt to retrieve its nexus offset.'
|
|
151
|
+
self.stormIsInPrint(emsg, msgs)
|
|
152
|
+
|
|
153
|
+
self.none(await core00.callStorm('return($lib.aha.del(00.newp...))'))
|
|
154
|
+
msgs = await core00.stormlist('aha.svc.list')
|
|
155
|
+
self.stormNotInPrint('00.newp', msgs)
|
|
156
|
+
|
|
157
|
+
# Fake a online record
|
|
158
|
+
guid = s_common.guid()
|
|
159
|
+
await aha.addAhaSvc('00.newp', info={'urlinfo': {'scheme': 'tcp',
|
|
160
|
+
'host': '0.0.0.0',
|
|
161
|
+
'port': '3030'},
|
|
162
|
+
'online': guid,
|
|
163
|
+
},
|
|
164
|
+
network='loop.vertex.link')
|
|
165
|
+
msgs = await core00.stormlist('aha.svc.list --nexus')
|
|
166
|
+
emsg = '00.newp.loop.vertex.link null true null 0.0.0.0 3030 ' \
|
|
167
|
+
'Failed to connect to Telepath service: "aha://00.newp.loop.vertex.link/" error:'
|
|
168
|
+
self.stormIsInPrint(emsg, msgs)
|
|
169
|
+
|
|
170
|
+
msgs = await core00.stormlist('aha.svc.stat --nexus 00.newp...')
|
|
171
|
+
emsg = '''Resolved 00.newp... to an AHA Service.
|
|
172
|
+
|
|
173
|
+
Name: 00.newp.loop.vertex.link
|
|
174
|
+
Online: true
|
|
175
|
+
Ready: null
|
|
176
|
+
Run iden: $lib.null
|
|
177
|
+
Cell iden: $lib.null
|
|
178
|
+
Leader: Service did not register itself with a leader name.
|
|
179
|
+
Nexus: Failed to connect to Telepath service: "aha://00.newp.loop.vertex.link/" error: [Errno 111] Connect call failed ('0.0.0.0', 3030)
|
|
180
|
+
Connection information:
|
|
181
|
+
host: 0.0.0.0
|
|
182
|
+
port: 3030
|
|
183
|
+
scheme: tcp
|
|
184
|
+
user: root'''
|
|
185
|
+
self.stormIsInPrint(emsg, msgs)
|
|
186
|
+
|
|
187
|
+
# Delete the fake service with its full service name
|
|
188
|
+
self.none(await core00.callStorm('return($lib.aha.del(00.newp.loop.vertex.link))'))
|
|
189
|
+
self.none(await core00.callStorm('return($lib.aha.get(00.newp...))'))
|
|
190
|
+
|
|
191
|
+
# Coverage for sad paths
|
|
192
|
+
with self.raises(s_exc.BadArg):
|
|
193
|
+
await core00.callStorm('$lib.aha.del(pool00...)')
|
|
194
|
+
|
|
195
|
+
with self.raises(s_exc.NoSuchName):
|
|
196
|
+
await core00.callStorm('$lib.aha.del(axon...)')
|
|
@@ -14,13 +14,13 @@ class StormlibCompressionTest(s_test.SynTest):
|
|
|
14
14
|
text = 'ohhai'
|
|
15
15
|
tenc = base64.urlsafe_b64encode((bz2.compress(text.encode()))).decode()
|
|
16
16
|
|
|
17
|
-
await core.nodes(f'[
|
|
18
|
-
await core.nodes(f'[
|
|
17
|
+
await core.nodes(f'[ tel:mob:telem=(node1,) :data="{tenc}" ]')
|
|
18
|
+
await core.nodes(f'[ tel:mob:telem=(node2,) :data="{text}" ]')
|
|
19
19
|
|
|
20
|
-
q = '
|
|
20
|
+
q = 'tel:mob:telem=(node1,) return($lib.compression.bzip2.un($lib.base64.decode(:data)).decode())'
|
|
21
21
|
self.eq(text, await core.callStorm(q))
|
|
22
22
|
|
|
23
|
-
q = '
|
|
23
|
+
q = 'tel:mob:telem=(node2,) return($lib.base64.encode($lib.compression.bzip2.en((:data).encode())))'
|
|
24
24
|
self.eq(tenc, await core.callStorm(q))
|
|
25
25
|
|
|
26
26
|
await self.asyncraises(s_exc.StormRuntimeError, core.nodes('$lib.compression.bzip2.en(foo)'))
|
|
@@ -31,13 +31,13 @@ class StormlibCompressionTest(s_test.SynTest):
|
|
|
31
31
|
text = 'ohhai'
|
|
32
32
|
tenc = base64.urlsafe_b64encode((gzip.compress(text.encode()))).decode()
|
|
33
33
|
|
|
34
|
-
await core.nodes(f'[
|
|
35
|
-
await core.nodes(f'[
|
|
34
|
+
await core.nodes(f'[ tel:mob:telem=(node1,) :data="{tenc}" ]')
|
|
35
|
+
await core.nodes(f'[ tel:mob:telem=(node2,) :data="{text}" ]')
|
|
36
36
|
|
|
37
|
-
q = '
|
|
37
|
+
q = 'tel:mob:telem=(node1,) return($lib.compression.gzip.un($lib.base64.decode(:data)).decode())'
|
|
38
38
|
self.eq(text, await core.callStorm(q))
|
|
39
39
|
|
|
40
|
-
q = '
|
|
40
|
+
q = 'tel:mob:telem=(node2,) return($lib.compression.gzip.en((:data).encode()))'
|
|
41
41
|
self.eq(text.encode(), gzip.decompress(await core.callStorm(q)))
|
|
42
42
|
|
|
43
43
|
await self.asyncraises(s_exc.StormRuntimeError, core.nodes('$lib.compression.gzip.en(foo)'))
|
|
@@ -48,13 +48,13 @@ class StormlibCompressionTest(s_test.SynTest):
|
|
|
48
48
|
text = 'ohhai'
|
|
49
49
|
tenc = base64.urlsafe_b64encode((zlib.compress(text.encode()))).decode()
|
|
50
50
|
|
|
51
|
-
await core.nodes(f'[
|
|
52
|
-
await core.nodes(f'[
|
|
51
|
+
await core.nodes(f'[ tel:mob:telem=(node1,) :data="{tenc}" ]')
|
|
52
|
+
await core.nodes(f'[ tel:mob:telem=(node2,) :data="{text}" ]')
|
|
53
53
|
|
|
54
|
-
q = '
|
|
54
|
+
q = 'tel:mob:telem=(node1,) return($lib.compression.zlib.un($lib.base64.decode(:data)).decode())'
|
|
55
55
|
self.eq(text, await core.callStorm(q))
|
|
56
56
|
|
|
57
|
-
q = '
|
|
57
|
+
q = 'tel:mob:telem=(node2,) return($lib.base64.encode($lib.compression.zlib.en((:data).encode())))'
|
|
58
58
|
self.eq(tenc, await core.callStorm(q))
|
|
59
59
|
|
|
60
60
|
await self.asyncraises(s_exc.StormRuntimeError, core.nodes('$lib.compression.zlib.en(foo)'))
|
|
@@ -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')
|
|
@@ -29,7 +29,7 @@ class StormlibSpooledTest(s_test.SynTest):
|
|
|
29
29
|
$set = $lib.spooled.set()
|
|
30
30
|
inet:ipv4 $set.add(:asn)
|
|
31
31
|
$set.rems((:asn,:asn))
|
|
32
|
-
[
|
|
32
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$set.list() ]
|
|
33
33
|
'''
|
|
34
34
|
nodes = await core.nodes(q)
|
|
35
35
|
self.len(1, nodes)
|
|
@@ -1343,34 +1343,34 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1343
1343
|
n2 = s_common.guid()
|
|
1344
1344
|
n3 = s_common.guid()
|
|
1345
1345
|
|
|
1346
|
-
nodes = await core.nodes('[
|
|
1346
|
+
nodes = await core.nodes('[tel:mob:telem="*" :data=$data]', opts={'vars': {'data': ghstr}})
|
|
1347
1347
|
self.len(1, nodes)
|
|
1348
1348
|
node1 = nodes[0]
|
|
1349
1349
|
|
|
1350
|
-
nodes = await core.nodes('[
|
|
1350
|
+
nodes = await core.nodes('[tel:mob:telem="*" :data=$data]', opts={'vars': {'data': mstr}})
|
|
1351
1351
|
self.len(1, nodes)
|
|
1352
1352
|
node2 = nodes[0]
|
|
1353
|
-
q = '''
|
|
1353
|
+
q = '''tel:mob:telem=$n1 $gzthing = :data
|
|
1354
1354
|
$foo = $lib.base64.decode($gzthing).gunzip()
|
|
1355
1355
|
$lib.print($foo)
|
|
1356
|
-
[(
|
|
1356
|
+
[( tel:mob:telem=$n2 :data=$foo.decode() )]'''
|
|
1357
1357
|
|
|
1358
1358
|
msgs = await core.stormlist(q, opts={'vars': {'n1': node1.ndef[1], 'n2': n2}})
|
|
1359
1359
|
self.stormHasNoWarnErr(msgs)
|
|
1360
1360
|
self.stormIsInPrint('ohhai', msgs)
|
|
1361
1361
|
|
|
1362
1362
|
# make sure we gunzip correctly
|
|
1363
|
-
nodes = await core.nodes('
|
|
1363
|
+
nodes = await core.nodes('tel:mob:telem=$valu', opts={'vars': {'valu': n2}})
|
|
1364
1364
|
self.len(1, nodes)
|
|
1365
1365
|
self.eq(hstr, nodes[0].get('data'))
|
|
1366
1366
|
|
|
1367
|
-
text = f'''
|
|
1368
|
-
[(
|
|
1367
|
+
text = f'''tel:mob:telem=$n2 $bar = :data
|
|
1368
|
+
[( tel:mob:telem=$n3 :data=$lib.base64.encode($bar.encode().gzip()) )]'''
|
|
1369
1369
|
msgs = await core.stormlist(text, opts={'vars': {'n2': node2.ndef[1], 'n3': n3}})
|
|
1370
1370
|
self.stormHasNoWarnErr(msgs)
|
|
1371
1371
|
|
|
1372
1372
|
# make sure we gzip correctly
|
|
1373
|
-
nodes = await core.nodes('
|
|
1373
|
+
nodes = await core.nodes('tel:mob:telem=$valu', opts={'vars': {'valu': n3}})
|
|
1374
1374
|
self.len(1, nodes)
|
|
1375
1375
|
self.eq(mstr.encode(), gzip.decompress(base64.urlsafe_b64decode(nodes[0].props['data'])))
|
|
1376
1376
|
|
|
@@ -1383,30 +1383,30 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1383
1383
|
n2 = s_common.guid()
|
|
1384
1384
|
n3 = s_common.guid()
|
|
1385
1385
|
|
|
1386
|
-
nodes = await core.nodes('[
|
|
1386
|
+
nodes = await core.nodes('[tel:mob:telem="*" :data=$data]', opts={'vars': {'data': ghstr}})
|
|
1387
1387
|
self.len(1, nodes)
|
|
1388
1388
|
node1 = nodes[0]
|
|
1389
|
-
nodes = await core.nodes('[
|
|
1389
|
+
nodes = await core.nodes('[tel:mob:telem="*" :data=$data]', opts={'vars': {'data': mstr}})
|
|
1390
1390
|
self.len(1, nodes)
|
|
1391
1391
|
node2 = nodes[0]
|
|
1392
1392
|
|
|
1393
|
-
q = '''
|
|
1393
|
+
q = '''tel:mob:telem=$valu $bzthing = :data $foo = $lib.base64.decode($bzthing).bunzip()
|
|
1394
1394
|
$lib.print($foo)
|
|
1395
|
-
[(
|
|
1395
|
+
[( tel:mob:telem=$n2 :data=$foo.decode() )] -tel:mob:telem=$valu'''
|
|
1396
1396
|
msgs = await core.stormlist(q, opts={'vars': {'valu': node1.ndef[1], 'n2': n2}})
|
|
1397
1397
|
self.stormHasNoWarnErr(msgs)
|
|
1398
1398
|
self.stormIsInPrint('ohhai', msgs)
|
|
1399
1399
|
|
|
1400
1400
|
# make sure we bunzip correctly
|
|
1401
1401
|
opts = {'vars': {'iden': n2}}
|
|
1402
|
-
nodes = await core.nodes('
|
|
1402
|
+
nodes = await core.nodes('tel:mob:telem=$iden', opts=opts)
|
|
1403
1403
|
self.len(1, nodes)
|
|
1404
1404
|
node = nodes[0]
|
|
1405
1405
|
self.eq(node.get('data'), hstr)
|
|
1406
1406
|
|
|
1407
1407
|
# bzip
|
|
1408
|
-
q = '''
|
|
1409
|
-
[(
|
|
1408
|
+
q = '''tel:mob:telem=$valu $bar = :data
|
|
1409
|
+
[( tel:mob:telem=$n3 :data=$lib.base64.encode($bar.encode().bzip()) )] -tel:mob:telem=$valu'''
|
|
1410
1410
|
nodes = await core.nodes(q, opts={'vars': {'valu': node2.ndef[1], 'n3': n3}})
|
|
1411
1411
|
self.len(1, nodes)
|
|
1412
1412
|
node = nodes[0]
|
|
@@ -1420,13 +1420,13 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1420
1420
|
valu = s_common.guid()
|
|
1421
1421
|
n2 = s_common.guid()
|
|
1422
1422
|
|
|
1423
|
-
nodes = await core.nodes('[
|
|
1423
|
+
nodes = await core.nodes('[tel:mob:telem=$valu :data=$data]', opts={'vars': {'valu': valu, 'data': ghstr}})
|
|
1424
1424
|
self.len(1, nodes)
|
|
1425
1425
|
node1 = nodes[0]
|
|
1426
1426
|
self.eq(node1.get('data'), ghstr)
|
|
1427
1427
|
|
|
1428
|
-
q = '''
|
|
1429
|
-
-
|
|
1428
|
+
q = '''tel:mob:telem=$valu $jzthing=:data $foo=$jzthing.encode().json() [(tel:mob:telem=$n2 :data=$foo)]
|
|
1429
|
+
-tel:mob:telem=$valu'''
|
|
1430
1430
|
nodes = await core.nodes(q, opts={'vars': {'valu': valu, 'n2': n2}})
|
|
1431
1431
|
self.len(1, nodes)
|
|
1432
1432
|
node2 = nodes[0]
|
|
@@ -1720,7 +1720,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1720
1720
|
q = '''
|
|
1721
1721
|
$set = $lib.set()
|
|
1722
1722
|
inet:ipv4 $set.add(:asn)
|
|
1723
|
-
[
|
|
1723
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$set.list() ]
|
|
1724
1724
|
'''
|
|
1725
1725
|
nodes = await core.nodes(q)
|
|
1726
1726
|
self.len(1, nodes)
|
|
@@ -1729,7 +1729,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1729
1729
|
q = '''
|
|
1730
1730
|
$set = $lib.set()
|
|
1731
1731
|
inet:ipv4 $set.adds((:asn,:asn))
|
|
1732
|
-
[
|
|
1732
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$set.list() ]
|
|
1733
1733
|
'''
|
|
1734
1734
|
nodes = await core.nodes(q)
|
|
1735
1735
|
self.len(1, nodes)
|
|
@@ -1739,7 +1739,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1739
1739
|
$set = $lib.set()
|
|
1740
1740
|
inet:ipv4 $set.adds((:asn,:asn))
|
|
1741
1741
|
{ +:asn=20 $set.rem(:asn) }
|
|
1742
|
-
[
|
|
1742
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$set.list() ]
|
|
1743
1743
|
'''
|
|
1744
1744
|
nodes = await core.nodes(q)
|
|
1745
1745
|
self.len(1, nodes)
|
|
@@ -1749,7 +1749,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
1749
1749
|
$set = $lib.set()
|
|
1750
1750
|
inet:ipv4 $set.add(:asn)
|
|
1751
1751
|
$set.rems((:asn,:asn))
|
|
1752
|
-
[
|
|
1752
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$set.list() ]
|
|
1753
1753
|
'''
|
|
1754
1754
|
nodes = await core.nodes(q)
|
|
1755
1755
|
self.len(1, nodes)
|
|
@@ -2151,7 +2151,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2151
2151
|
q = '''
|
|
2152
2152
|
inet:fqdn=vertex.link -> inet:dns:a -> inet:ipv4
|
|
2153
2153
|
$idens = $path.idens()
|
|
2154
|
-
[
|
|
2154
|
+
[ tel:mob:telem="*" ] +tel:mob:telem [ :data=$idens ]
|
|
2155
2155
|
'''
|
|
2156
2156
|
|
|
2157
2157
|
idens = (
|
|
@@ -2699,6 +2699,17 @@ class StormTypesTest(s_test.SynTest):
|
|
|
2699
2699
|
await core.addUserRule(user, (True, ('storm', 'lib', 'telepath', 'open', 'cell')))
|
|
2700
2700
|
self.len(2, await core.callStorm('return ( $lib.telepath.open($url).ipv4s() )', opts=opts))
|
|
2701
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
|
+
|
|
2702
2713
|
async def test_storm_lib_queue(self):
|
|
2703
2714
|
|
|
2704
2715
|
async with self.getTestCore() as core:
|
|
@@ -4474,7 +4485,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4474
4485
|
|
|
4475
4486
|
async with self.getTestCore() as core:
|
|
4476
4487
|
|
|
4477
|
-
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())')
|
|
4478
4489
|
self.eq('', cdef.get('doc'))
|
|
4479
4490
|
self.eq('', cdef.get('name'))
|
|
4480
4491
|
|
|
@@ -4490,7 +4501,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4490
4501
|
with self.raises(s_exc.BadArg):
|
|
4491
4502
|
await core.callStorm('return($lib.cron.get($iden).set(hehe, haha))', opts=opts)
|
|
4492
4503
|
|
|
4493
|
-
mesgs = await core.stormlist('cron.add --hour +1 {[
|
|
4504
|
+
mesgs = await core.stormlist('cron.add --hour +1 {[tel:mob:telem=*]} --name myname --doc mydoc')
|
|
4494
4505
|
for mesg in mesgs:
|
|
4495
4506
|
if mesg[0] == 'print':
|
|
4496
4507
|
iden0 = mesg[1]['mesg'].split(' ')[-1]
|
|
@@ -4595,7 +4606,7 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4595
4606
|
nextlayroffs = await layr.getEditOffs() + 1
|
|
4596
4607
|
|
|
4597
4608
|
# Start simple: add a cron job that creates a node every minute
|
|
4598
|
-
q = "cron.add --minute +1 {[
|
|
4609
|
+
q = "cron.add --minute +1 {[meta:note='*' :type=m1]}"
|
|
4599
4610
|
mesgs = await core.stormlist(q)
|
|
4600
4611
|
self.stormIsInPrint('Created cron job', mesgs)
|
|
4601
4612
|
for mesg in mesgs:
|
|
@@ -4637,24 +4648,24 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4637
4648
|
|
|
4638
4649
|
# Make sure it ran
|
|
4639
4650
|
await layr.waitEditOffs(nextlayroffs, timeout=5)
|
|
4640
|
-
self.eq(1, await prox.count('
|
|
4651
|
+
self.eq(1, await prox.count('meta:note:type=m1'))
|
|
4641
4652
|
|
|
4642
|
-
q = "cron.mod $guid { [
|
|
4653
|
+
q = "cron.mod $guid { [meta:note='*' :type=m2] }"
|
|
4643
4654
|
mesgs = await core.stormlist(q, opts={'vars': {'guid': guid[:6]}})
|
|
4644
4655
|
self.stormIsInPrint(f'Modified cron job: {guid}', mesgs)
|
|
4645
4656
|
|
|
4646
|
-
q = "cron.mod xxx { [
|
|
4657
|
+
q = "cron.mod xxx { [meta:note='*' :type=m2] }"
|
|
4647
4658
|
mesgs = await core.stormlist(q)
|
|
4648
4659
|
self.stormIsInErr('does not match', mesgs)
|
|
4649
4660
|
|
|
4650
4661
|
# Make sure the old one didn't run and the new query ran
|
|
4651
4662
|
unixtime += 60
|
|
4652
4663
|
await asyncio.sleep(0)
|
|
4653
|
-
self.eq(1, await prox.count('
|
|
4664
|
+
self.eq(1, await prox.count('meta:note:type=m1'))
|
|
4654
4665
|
# UNG WTF
|
|
4655
4666
|
await asyncio.sleep(0)
|
|
4656
4667
|
await asyncio.sleep(0)
|
|
4657
|
-
self.eq(1, await prox.count('
|
|
4668
|
+
self.eq(1, await prox.count('meta:note:type=m2'))
|
|
4658
4669
|
|
|
4659
4670
|
# Delete the job
|
|
4660
4671
|
q = f"cron.del {guid}"
|
|
@@ -4667,8 +4678,8 @@ class StormTypesTest(s_test.SynTest):
|
|
|
4667
4678
|
|
|
4668
4679
|
# Make sure deleted job didn't run
|
|
4669
4680
|
unixtime += 60
|
|
4670
|
-
self.eq(1, await prox.count('
|
|
4671
|
-
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'))
|
|
4672
4683
|
|
|
4673
4684
|
# Test fixed minute, i.e. every hour at 17 past
|
|
4674
4685
|
unixtime = datetime.datetime(year=2018, month=12, day=5, hour=7, minute=10,
|