synapse 2.166.0__py311-none-any.whl → 2.168.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 +55 -12
- synapse/exc.py +1 -0
- synapse/lib/aha.py +4 -1
- synapse/lib/base.py +11 -4
- synapse/lib/cell.py +11 -2
- synapse/lib/hive.py +11 -0
- synapse/lib/layer.py +2 -0
- synapse/lib/modelrev.py +6 -0
- synapse/lib/modules.py +1 -0
- synapse/lib/node.py +4 -2
- synapse/lib/schemas.py +1 -1
- synapse/lib/stormlib/aha.py +385 -20
- synapse/lib/stormlib/easyperm.py +8 -0
- synapse/lib/stormlib/macro.py +11 -18
- synapse/lib/stormlib/stix.py +1 -1
- synapse/lib/stormtypes.py +25 -2
- synapse/lib/types.py +2 -0
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +5 -3
- synapse/models/base.py +8 -0
- synapse/models/files.py +3 -0
- synapse/models/planning.py +161 -0
- synapse/telepath.py +1 -0
- synapse/tests/files/stormpkg/dotstorm/dotstorm.yaml +3 -0
- synapse/tests/test_cortex.py +40 -3
- synapse/tests/test_lib_aha.py +8 -4
- 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_trigger.py +3 -3
- synapse/tests/test_lib_view.py +50 -3
- synapse/tests/test_model_files.py +3 -0
- synapse/tests/test_model_planning.py +126 -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.168.0.dist-info}/METADATA +3 -3
- {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/RECORD +53 -50
- {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/LICENSE +0 -0
- {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/WHEEL +0 -0
- {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/top_level.txt +0 -0
synapse/lib/stormlib/aha.py
CHANGED
|
@@ -1,43 +1,169 @@
|
|
|
1
|
-
import synapse.
|
|
1
|
+
import synapse.exc as s_exc
|
|
2
2
|
import synapse.lib.stormtypes as s_stormtypes
|
|
3
3
|
|
|
4
|
+
@s_stormtypes.registry.registerLib
|
|
5
|
+
class AhaLib(s_stormtypes.Lib):
|
|
6
|
+
'''
|
|
7
|
+
A Storm Library for interacting with AHA.
|
|
8
|
+
'''
|
|
9
|
+
|
|
10
|
+
_storm_locals = (
|
|
11
|
+
{'name': 'del', 'desc': '''Delete a service from AHA.
|
|
12
|
+
|
|
13
|
+
Examples:
|
|
14
|
+
Deleting a service with its relative name::
|
|
15
|
+
|
|
16
|
+
$lib.aha.del(00.mysvc...)
|
|
17
|
+
|
|
18
|
+
Deleting a service with its full name::
|
|
19
|
+
|
|
20
|
+
$lib.aha.del(00.mysvc.loop.vertex.link)
|
|
21
|
+
''',
|
|
22
|
+
'type': {'type': 'function', '_funcname': '_methAhaDel',
|
|
23
|
+
'args': (
|
|
24
|
+
{'name': 'svcname', 'type': 'str',
|
|
25
|
+
'desc': 'The name of the service to delete. It is easiest to use the relative name of a service, ending with "...".', },
|
|
26
|
+
),
|
|
27
|
+
'returns': {'type': 'null'}}},
|
|
28
|
+
{'name': 'get', 'desc': '''Get information about an AHA service.
|
|
29
|
+
|
|
30
|
+
Examples:
|
|
31
|
+
Getting service information with a relative name::
|
|
32
|
+
|
|
33
|
+
$lib.aha.get(00.cortex...)
|
|
34
|
+
|
|
35
|
+
Getting service information with its full name::
|
|
36
|
+
|
|
37
|
+
$lib.aha.get(00.cortex.loop.vertex.link)
|
|
38
|
+
''',
|
|
39
|
+
'type': {'type': 'function', '_funcname': '_methAhaGet',
|
|
40
|
+
'args': (
|
|
41
|
+
{'name': 'svcname', 'type': 'str',
|
|
42
|
+
'desc': 'The name of the AHA service to look up. It is easiest to use the relative name of a service, ending with "...".', },
|
|
43
|
+
{'name': 'filters', 'type': 'dict', 'default': None,
|
|
44
|
+
'desc': 'An optional dictionary of filters to use when resolving the AHA service.'}
|
|
45
|
+
),
|
|
46
|
+
'returns': {'type': ('null', 'dict'),
|
|
47
|
+
'desc': 'The AHA service information dictionary, or $lib.null.', }}},
|
|
48
|
+
{'name': 'list', 'desc': 'Enumerate all of the AHA services.',
|
|
49
|
+
'type': {'type': 'function', '_funcname': '_methAhaList', 'args': (),
|
|
50
|
+
'returns': {'name': 'Yields', 'type': 'list',
|
|
51
|
+
'desc': 'The AHA service dictionaries.', }}},
|
|
52
|
+
)
|
|
53
|
+
_storm_lib_path = ('aha',)
|
|
54
|
+
def getObjLocals(self):
|
|
55
|
+
return {
|
|
56
|
+
'del': self._methAhaDel,
|
|
57
|
+
'get': self._methAhaGet,
|
|
58
|
+
'list': self._methAhaList,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
62
|
+
async def _methAhaList(self):
|
|
63
|
+
self.runt.reqAdmin()
|
|
64
|
+
proxy = await self.runt.snap.core.reqAhaProxy()
|
|
65
|
+
async for info in proxy.getAhaSvcs():
|
|
66
|
+
yield info
|
|
67
|
+
|
|
68
|
+
async def _methAhaDel(self, svcname):
|
|
69
|
+
self.runt.reqAdmin()
|
|
70
|
+
svcname = await s_stormtypes.tostr(svcname)
|
|
71
|
+
proxy = await self.runt.snap.core.reqAhaProxy()
|
|
72
|
+
svc = await proxy.getAhaSvc(svcname)
|
|
73
|
+
if svc is None:
|
|
74
|
+
raise s_exc.NoSuchName(mesg=f'No AHA service for {svcname=}')
|
|
75
|
+
if svc.get('services'): # It is an AHA Pool!
|
|
76
|
+
mesg = f'Cannot use $lib.aha.del() to remove an AHA Pool. Use $lib.aha.pool.del(); {svcname=}'
|
|
77
|
+
raise s_exc.BadArg(mesg=mesg)
|
|
78
|
+
return await proxy.delAhaSvc(svc.get('svcname'), network=svc.get('svcnetw'))
|
|
79
|
+
|
|
80
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
81
|
+
async def _methAhaGet(self, svcname, filters=None):
|
|
82
|
+
self.runt.reqAdmin()
|
|
83
|
+
svcname = await s_stormtypes.tostr(svcname)
|
|
84
|
+
filters = await s_stormtypes.toprim(filters)
|
|
85
|
+
proxy = await self.runt.snap.core.reqAhaProxy()
|
|
86
|
+
return await proxy.getAhaSvc(svcname, filters=filters)
|
|
87
|
+
|
|
4
88
|
@s_stormtypes.registry.registerLib
|
|
5
89
|
class AhaPoolLib(s_stormtypes.Lib):
|
|
6
90
|
'''
|
|
7
91
|
A Storm Library for interacting with AHA service pools.
|
|
8
92
|
'''
|
|
93
|
+
|
|
94
|
+
_storm_locals = (
|
|
95
|
+
{'name': 'add', 'desc': '''Add a new AHA service pool.
|
|
96
|
+
|
|
97
|
+
Examples:
|
|
98
|
+
Add a pool via its relative name::
|
|
99
|
+
|
|
100
|
+
$lib.aha.pool.add(pool00.cortex...)
|
|
101
|
+
''',
|
|
102
|
+
'type': {'type': 'function', '_funcname': '_methPoolAdd',
|
|
103
|
+
'args': (
|
|
104
|
+
{'name': 'name', 'type': 'str',
|
|
105
|
+
'desc': 'The name of the pool to add. It is easiest to use the relative name of a pool, ending with "...".', },
|
|
106
|
+
),
|
|
107
|
+
'returns': {'type': 'aha:pool'}}},
|
|
108
|
+
{'name': 'del', 'desc': '''Delete an existing AHA service pool.
|
|
109
|
+
|
|
110
|
+
Examples:
|
|
111
|
+
Delete a pool via its relative name::
|
|
112
|
+
|
|
113
|
+
$lib.aha.pool.del(pool00.cortex...)
|
|
114
|
+
''',
|
|
115
|
+
'type': {'type': 'function', '_funcname': '_methPoolDel',
|
|
116
|
+
'args': (
|
|
117
|
+
{'name': 'name', 'type': 'str',
|
|
118
|
+
'desc': 'The name of the pool to delete. It is easiest to use the relative name of a pool, ending with "...".', },
|
|
119
|
+
),
|
|
120
|
+
'returns': {'type': 'dict', 'desc': 'The AHA pool definition that was deleted.'}}},
|
|
121
|
+
{'name': 'get', 'desc': 'Get an existing AHA service pool.',
|
|
122
|
+
'type': {'type': 'function', '_funcname': '_methPoolGet',
|
|
123
|
+
'args': (
|
|
124
|
+
{'name': 'name', 'type': 'str',
|
|
125
|
+
'desc': 'The name of the pool to get. It is easiest to use the relative name of a pool, ending with "...".', },
|
|
126
|
+
),
|
|
127
|
+
'returns': {'type': ['null', 'aha:pool'], 'desc': 'The pool if it exists, or $lib.null.'}}},
|
|
128
|
+
{'name': 'list', 'desc': 'Enumerate all of the AHA service pools.',
|
|
129
|
+
'type': {'type': 'function', '_funcname': '_methPoolList',
|
|
130
|
+
'returns': {'name': 'yields', 'type': 'aha:pool'}}},
|
|
131
|
+
)
|
|
9
132
|
_storm_lib_path = ('aha', 'pool')
|
|
10
133
|
|
|
11
134
|
def getObjLocals(self):
|
|
12
135
|
return {
|
|
13
|
-
'add': self.
|
|
14
|
-
'del': self.
|
|
15
|
-
'get': self.
|
|
16
|
-
'list': self.
|
|
136
|
+
'add': self._methPoolAdd,
|
|
137
|
+
'del': self._methPoolDel,
|
|
138
|
+
'get': self._methPoolGet,
|
|
139
|
+
'list': self._methPoolList,
|
|
17
140
|
}
|
|
18
141
|
|
|
19
|
-
async def
|
|
142
|
+
async def _methPoolAdd(self, name):
|
|
20
143
|
self.runt.reqAdmin()
|
|
144
|
+
name = await s_stormtypes.tostr(name)
|
|
21
145
|
proxy = await self.runt.snap.core.reqAhaProxy()
|
|
22
146
|
poolinfo = {'creator': self.runt.user.iden}
|
|
23
147
|
poolinfo = await proxy.addAhaPool(name, poolinfo)
|
|
24
148
|
return AhaPool(self.runt, poolinfo)
|
|
25
149
|
|
|
26
|
-
async def
|
|
150
|
+
async def _methPoolDel(self, name):
|
|
27
151
|
self.runt.reqAdmin()
|
|
152
|
+
name = await s_stormtypes.tostr(name)
|
|
28
153
|
proxy = await self.runt.snap.core.reqAhaProxy()
|
|
29
154
|
return await proxy.delAhaPool(name)
|
|
30
155
|
|
|
31
|
-
|
|
156
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
157
|
+
async def _methPoolGet(self, name):
|
|
32
158
|
self.runt.reqAdmin()
|
|
159
|
+
name = await s_stormtypes.tostr(name)
|
|
33
160
|
proxy = await self.runt.snap.core.reqAhaProxy()
|
|
34
161
|
poolinfo = await proxy.getAhaPool(name)
|
|
35
162
|
if poolinfo is not None:
|
|
36
163
|
return AhaPool(self.runt, poolinfo)
|
|
37
164
|
|
|
38
165
|
@s_stormtypes.stormfunc(readonly=True)
|
|
39
|
-
async def
|
|
40
|
-
|
|
166
|
+
async def _methPoolList(self):
|
|
41
167
|
self.runt.reqAdmin()
|
|
42
168
|
proxy = await self.runt.snap.core.reqAhaProxy()
|
|
43
169
|
|
|
@@ -49,6 +175,36 @@ class AhaPool(s_stormtypes.StormType):
|
|
|
49
175
|
'''
|
|
50
176
|
Implements the Storm API for an AHA pool.
|
|
51
177
|
'''
|
|
178
|
+
_storm_locals = (
|
|
179
|
+
{'name': 'add', 'desc': '''Add a service to the AHA pool
|
|
180
|
+
|
|
181
|
+
Examples:
|
|
182
|
+
Add a service to a pool with its relative name::
|
|
183
|
+
|
|
184
|
+
$pool = $lib.aha.pool.get(pool00.cortex...)
|
|
185
|
+
$pool.add(00.cortex...)
|
|
186
|
+
''',
|
|
187
|
+
'type': {'type': 'function', '_funcname': '_methPoolSvcAdd',
|
|
188
|
+
'args': (
|
|
189
|
+
{'name': 'svcname', 'type': 'str',
|
|
190
|
+
'desc': 'The name of the AHA service to add. It is easiest to use the relative name of a service, ending with "...".', },
|
|
191
|
+
),
|
|
192
|
+
'returns': {'type': 'null', }}},
|
|
193
|
+
{'name': 'del', 'desc': '''Remove a service from the AHA pool.
|
|
194
|
+
|
|
195
|
+
Examples:
|
|
196
|
+
Remove a service from a pool with its relative name::
|
|
197
|
+
|
|
198
|
+
$pool = $lib.aha.pool.get(pool00.cortex...)
|
|
199
|
+
$pool.del(00.cortex...)
|
|
200
|
+
''',
|
|
201
|
+
'type': {'type': 'function', '_funcname': '_methPoolSvcDel',
|
|
202
|
+
'args': (
|
|
203
|
+
{'name': 'svcname', 'type': 'str',
|
|
204
|
+
'desc': 'The name of the AHA service to remove. It is easiest to use the relative name of a service, ending with "...".', },
|
|
205
|
+
),
|
|
206
|
+
'returns': {'type': ['null', 'str'], 'desc': 'The service removed from the pool or null if a service was not removed.'}}},
|
|
207
|
+
)
|
|
52
208
|
_storm_typename = 'aha:pool'
|
|
53
209
|
|
|
54
210
|
def __init__(self, runt, poolinfo):
|
|
@@ -57,8 +213,8 @@ class AhaPool(s_stormtypes.StormType):
|
|
|
57
213
|
self.poolinfo = poolinfo
|
|
58
214
|
|
|
59
215
|
self.locls.update({
|
|
60
|
-
'add': self.
|
|
61
|
-
'del': self.
|
|
216
|
+
'add': self._methPoolSvcAdd,
|
|
217
|
+
'del': self._methPoolSvcDel,
|
|
62
218
|
})
|
|
63
219
|
|
|
64
220
|
async def stormrepr(self):
|
|
@@ -67,7 +223,7 @@ class AhaPool(s_stormtypes.StormType):
|
|
|
67
223
|
async def _derefGet(self, name):
|
|
68
224
|
return self.poolinfo.get(name)
|
|
69
225
|
|
|
70
|
-
async def
|
|
226
|
+
async def _methPoolSvcAdd(self, svcname):
|
|
71
227
|
self.runt.reqAdmin()
|
|
72
228
|
svcname = await s_stormtypes.tostr(svcname)
|
|
73
229
|
|
|
@@ -80,16 +236,27 @@ class AhaPool(s_stormtypes.StormType):
|
|
|
80
236
|
|
|
81
237
|
self.poolinfo.update(poolinfo)
|
|
82
238
|
|
|
83
|
-
async def
|
|
239
|
+
async def _methPoolSvcDel(self, svcname):
|
|
84
240
|
self.runt.reqAdmin()
|
|
85
241
|
svcname = await s_stormtypes.tostr(svcname)
|
|
86
242
|
|
|
87
243
|
proxy = await self.runt.snap.core.reqAhaProxy()
|
|
88
244
|
|
|
89
245
|
poolname = self.poolinfo.get('name')
|
|
90
|
-
await proxy.delAhaPoolSvc(poolname, svcname)
|
|
246
|
+
newinfo = await proxy.delAhaPoolSvc(poolname, svcname)
|
|
247
|
+
|
|
248
|
+
tname = svcname
|
|
249
|
+
if tname.endswith('...'):
|
|
250
|
+
tname = tname[:-2]
|
|
251
|
+
deleted_service = None
|
|
252
|
+
deleted_services = [svc for svc in self.poolinfo.get('services').keys()
|
|
253
|
+
if svc not in newinfo.get('services') and svc.startswith(tname)]
|
|
254
|
+
if deleted_services:
|
|
255
|
+
deleted_service = deleted_services[0]
|
|
91
256
|
|
|
92
|
-
self.poolinfo =
|
|
257
|
+
self.poolinfo = newinfo
|
|
258
|
+
|
|
259
|
+
return deleted_service
|
|
93
260
|
|
|
94
261
|
stormcmds = (
|
|
95
262
|
{
|
|
@@ -146,7 +313,7 @@ stormcmds = (
|
|
|
146
313
|
),
|
|
147
314
|
'storm': '''
|
|
148
315
|
$pool = $lib.aha.pool.get($cmdopts.poolname)
|
|
149
|
-
if (not $pool) { $lib.exit(`No AHA
|
|
316
|
+
if (not $pool) { $lib.exit(`No AHA service pool named: {$cmdopts.poolname}`) }
|
|
150
317
|
|
|
151
318
|
$pool.add($cmdopts.svcname)
|
|
152
319
|
$lib.print(`AHA service ({$cmdopts.svcname}) added to service pool ({$pool.name})`)
|
|
@@ -161,10 +328,208 @@ stormcmds = (
|
|
|
161
328
|
),
|
|
162
329
|
'storm': '''
|
|
163
330
|
$pool = $lib.aha.pool.get($cmdopts.poolname)
|
|
164
|
-
if (not $pool) { $lib.exit(`No AHA
|
|
331
|
+
if (not $pool) { $lib.exit(`No AHA service pool named: {$cmdopts.poolname}`) }
|
|
332
|
+
|
|
333
|
+
$svc = $pool.del($cmdopts.svcname)
|
|
334
|
+
if $svc {
|
|
335
|
+
$lib.print(`AHA service ({$svc}) removed from service pool ({$pool.name})`)
|
|
336
|
+
} else {
|
|
337
|
+
$lib.print(`Did not remove ({$cmdopts.svcname}) from the service pool.`)
|
|
338
|
+
}
|
|
339
|
+
''',
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
'name': 'aha.svc.stat',
|
|
343
|
+
'descr': '''Show all information for a specific AHA service.
|
|
165
344
|
|
|
166
|
-
|
|
167
|
-
|
|
345
|
+
If the --nexus argument is given, the Cortex will attempt to connect the service and report the Nexus offset of the service.
|
|
346
|
+
|
|
347
|
+
The ready value indicates that a service has entered into the realtime change window for synchronizing changes from its leader.
|
|
168
348
|
''',
|
|
349
|
+
'cmdargs': (
|
|
350
|
+
('svc', {'help': 'The service to inspect.'}),
|
|
351
|
+
('--nexus', {'help': 'Try to connect to online services and report their nexus offset.',
|
|
352
|
+
'default': False, 'action': 'store_true'}),
|
|
353
|
+
),
|
|
354
|
+
'storm': '''
|
|
355
|
+
function _getNexus(svcname) {
|
|
356
|
+
$_url = `aha://{$svcname}/`
|
|
357
|
+
try {
|
|
358
|
+
$_prox = $lib.telepath.open($_url)
|
|
359
|
+
$_info = $_prox.getCellInfo()
|
|
360
|
+
return ( $_info.cell.nexsindx )
|
|
361
|
+
} catch * as _err {
|
|
362
|
+
$_emsg = $_err.mesg
|
|
363
|
+
if ($_emsg = null ) {
|
|
364
|
+
$_emsg = `{$_err}`
|
|
365
|
+
}
|
|
366
|
+
return ( $_emsg )
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
$svc = $lib.aha.get($cmdopts.svc)
|
|
371
|
+
if ($svc = null) {
|
|
372
|
+
$lib.print(`No service found for: "{$cmdopts.svc}"`)
|
|
373
|
+
} else {
|
|
374
|
+
$services = $svc.services
|
|
375
|
+
if $services {
|
|
376
|
+
$lib.print(`Resolved {$cmdopts.svc} to an AHA Pool.\n`)
|
|
377
|
+
$lib.print(`The pool currently has {$lib.len($services)} members.`)
|
|
378
|
+
|
|
379
|
+
$lib.print(`AHA Pool: {$svc.name}`)
|
|
380
|
+
for ($_svcname, $_svcinfo) in $services {
|
|
381
|
+
$lib.print(`Member: {$_svcname}`)
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
$lib.print(`Resolved {$cmdopts.svc} to an AHA Service.\n`)
|
|
385
|
+
$svcinfo = $svc.svcinfo
|
|
386
|
+
$leader = $svcinfo.leader
|
|
387
|
+
if ($leader = null) {
|
|
388
|
+
$leader = 'Service did not register itself with a leader name.'
|
|
389
|
+
}
|
|
390
|
+
$online = false
|
|
391
|
+
if $svcinfo.online {
|
|
392
|
+
$online = true
|
|
393
|
+
}
|
|
394
|
+
$ready = 'null'
|
|
395
|
+
if $lib.dict.has($svcinfo, ready) {
|
|
396
|
+
$ready = `{$svcinfo.ready}`
|
|
397
|
+
}
|
|
398
|
+
$lib.print(`Name: {$svc.name}`)
|
|
399
|
+
$lib.print(`Online: {$online}`)
|
|
400
|
+
$lib.print(`Ready: {$ready}`)
|
|
401
|
+
$lib.print(`Run iden: {$svcinfo.run}`)
|
|
402
|
+
$lib.print(`Cell iden: {$svcinfo.iden}`)
|
|
403
|
+
$lib.print(`Leader: {$leader}`)
|
|
404
|
+
|
|
405
|
+
if $cmdopts.nexus {
|
|
406
|
+
if $svcinfo.online {
|
|
407
|
+
$nexusOffset = $_getNexus($svc.name)
|
|
408
|
+
} else {
|
|
409
|
+
$nexusOffset = 'Service is not online. Will not attempt to retrieve its nexus offset.'
|
|
410
|
+
}
|
|
411
|
+
$lib.print(`Nexus: {$nexusOffset}`)
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
$lib.print('Connection information:')
|
|
415
|
+
$urlinfo = $svcinfo.urlinfo
|
|
416
|
+
$keys = $lib.dict.keys($urlinfo)
|
|
417
|
+
$keys.sort()
|
|
418
|
+
for $k in $keys {
|
|
419
|
+
$dk = `{$k}:`
|
|
420
|
+
$dk = $dk.ljust(12)
|
|
421
|
+
$lib.print(` {$dk}{$urlinfo.$k}`)
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
'''
|
|
169
426
|
},
|
|
427
|
+
{
|
|
428
|
+
'name': 'aha.svc.list',
|
|
429
|
+
'descr': '''List AHA services.
|
|
430
|
+
|
|
431
|
+
If the --nexus argument is given, the Cortex will attempt to connect to each service and report the Nexus offset of the service.
|
|
432
|
+
|
|
433
|
+
The ready column indicates that a service has entered into the realtime change window for synchronizing changes from its leader.''',
|
|
434
|
+
'cmdargs': (
|
|
435
|
+
('--nexus', {'help': 'Try to connect to online services and report their nexus offset.',
|
|
436
|
+
'default': False, 'action': 'store_true'}),
|
|
437
|
+
),
|
|
438
|
+
'storm': '''
|
|
439
|
+
function _getNexus(svcname) {
|
|
440
|
+
$_url = `aha://{$svcname}/`
|
|
441
|
+
try {
|
|
442
|
+
$_prox = $lib.telepath.open($_url)
|
|
443
|
+
$_info = $_prox.getCellInfo()
|
|
444
|
+
return ( $_info.cell.nexsindx )
|
|
445
|
+
} catch * as _err {
|
|
446
|
+
$_emsg = $_err.mesg
|
|
447
|
+
if ($_emsg = null ) {
|
|
448
|
+
$_emsg = `{$_err}`
|
|
449
|
+
}
|
|
450
|
+
return ( $_emsg )
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
$svcs = ()
|
|
455
|
+
for $svc in $lib.aha.list() {
|
|
456
|
+
$svcs.append($svc)
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if ($lib.len($svcs) = 0) {
|
|
460
|
+
$lib.print('No AHA services registered.')
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
$columns = 'Name Leader Online Ready Host Port '
|
|
464
|
+
if $cmdopts.nexus {
|
|
465
|
+
$columns = `{$columns} Nexus`
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
$leaders = $lib.set()
|
|
469
|
+
for $info in $svcs {
|
|
470
|
+
$svcinfo = $info.svcinfo
|
|
471
|
+
if $svcinfo {
|
|
472
|
+
if ($info.svcname = $svcinfo.leader) {
|
|
473
|
+
$leaders.add($svcinfo.run)
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
$lib.print($columns)
|
|
479
|
+
|
|
480
|
+
for $info in $svcs {
|
|
481
|
+
$name = $info.name
|
|
482
|
+
$nexusOffset = (null)
|
|
483
|
+
$svcinfo = $info.svcinfo
|
|
484
|
+
|
|
485
|
+
if $cmdopts.nexus {
|
|
486
|
+
if $svcinfo.online {
|
|
487
|
+
$nexusOffset = $_getNexus($name)
|
|
488
|
+
} else {
|
|
489
|
+
$nexusOffset = 'Service is not online. Will not attempt to retrieve its nexus offset.'
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
$name=$name.ljust(45)
|
|
493
|
+
|
|
494
|
+
$online = false
|
|
495
|
+
if $svcinfo.online {
|
|
496
|
+
$online = true
|
|
497
|
+
}
|
|
498
|
+
$online = $online.ljust(6)
|
|
499
|
+
|
|
500
|
+
$urlinfo = $svcinfo.urlinfo
|
|
501
|
+
|
|
502
|
+
$host = $urlinfo.host
|
|
503
|
+
$host = $host.ljust(15)
|
|
504
|
+
|
|
505
|
+
$port = $lib.cast(str, $urlinfo.port) // Cast to str
|
|
506
|
+
$port = $port.ljust(5)
|
|
507
|
+
|
|
508
|
+
$ready = 'null'
|
|
509
|
+
if $lib.dict.has($svcinfo, ready) {
|
|
510
|
+
$ready = `{$svcinfo.ready}`
|
|
511
|
+
}
|
|
512
|
+
$ready = $ready.ljust(5)
|
|
513
|
+
|
|
514
|
+
$leader = null
|
|
515
|
+
if ( $svcinfo.leader != null ) {
|
|
516
|
+
if $leaders.has($svcinfo.run) {
|
|
517
|
+
$leader = true
|
|
518
|
+
} else {
|
|
519
|
+
$leader = false
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
$leader = $leader.ljust(6)
|
|
523
|
+
|
|
524
|
+
if $info {
|
|
525
|
+
$s = `{$name} {$leader} {$online} {$ready} {$host} {$port}`
|
|
526
|
+
if ($nexusOffset != null) {
|
|
527
|
+
$s = `{$s} {$nexusOffset}`
|
|
528
|
+
}
|
|
529
|
+
$lib.print($s)
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
'''
|
|
534
|
+
}
|
|
170
535
|
)
|
synapse/lib/stormlib/easyperm.py
CHANGED
|
@@ -51,6 +51,14 @@ class LibEasyPerm(s_stormtypes.Lib):
|
|
|
51
51
|
'desc': 'Optional error message to present if user does not have required permission level.'},
|
|
52
52
|
),
|
|
53
53
|
'returns': {'type': 'null'}}},
|
|
54
|
+
{'name': 'level.admin', 'desc': 'Constant for admin permission.',
|
|
55
|
+
'type': 'int', },
|
|
56
|
+
{'name': 'level.deny', 'desc': 'Constant for deny permission.',
|
|
57
|
+
'type': 'int', },
|
|
58
|
+
{'name': 'level.edit', 'desc': 'Constant for edit permission.',
|
|
59
|
+
'type': 'int', },
|
|
60
|
+
{'name': 'level.read', 'desc': 'Constant for read permission.',
|
|
61
|
+
'type': 'int', },
|
|
54
62
|
)
|
|
55
63
|
_storm_lib_path = ('auth', 'easyperm')
|
|
56
64
|
|
synapse/lib/stormlib/macro.py
CHANGED
|
@@ -34,7 +34,7 @@ stormcmds = [
|
|
|
34
34
|
'name': 'macro.del',
|
|
35
35
|
'descr': macro_del_descr,
|
|
36
36
|
'cmdargs': (
|
|
37
|
-
('name', {'help': 'The name of the macro to delete.'}),
|
|
37
|
+
('name', {'type': 'str', 'help': 'The name of the macro to delete.'}),
|
|
38
38
|
),
|
|
39
39
|
'storm': '''
|
|
40
40
|
$lib.macro.del($cmdopts.name)
|
|
@@ -45,7 +45,7 @@ stormcmds = [
|
|
|
45
45
|
'name': 'macro.set',
|
|
46
46
|
'descr': macro_set_descr,
|
|
47
47
|
'cmdargs': (
|
|
48
|
-
('name', {'help': 'The name of the macro to set.'}),
|
|
48
|
+
('name', {'type': 'str', 'help': 'The name of the macro to set.'}),
|
|
49
49
|
('storm', {'help': 'The storm command string or embedded query to set.'}),
|
|
50
50
|
),
|
|
51
51
|
'storm': '''
|
|
@@ -57,7 +57,7 @@ stormcmds = [
|
|
|
57
57
|
'name': 'macro.get',
|
|
58
58
|
'descr': macro_get_descr,
|
|
59
59
|
'cmdargs': (
|
|
60
|
-
('name', {'help': 'The name of the macro to display.'}),
|
|
60
|
+
('name', {'type': 'str', 'help': 'The name of the macro to display.'}),
|
|
61
61
|
),
|
|
62
62
|
'storm': '''
|
|
63
63
|
$mdef = $lib.macro.get($cmdopts.name)
|
|
@@ -74,8 +74,14 @@ stormcmds = [
|
|
|
74
74
|
'storm': '''
|
|
75
75
|
$count = $(0)
|
|
76
76
|
for ($name, $mdef) in $lib.macro.list() {
|
|
77
|
-
$user = $lib.auth.users.get($mdef.
|
|
78
|
-
$
|
|
77
|
+
$user = $lib.auth.users.get($mdef.creator)
|
|
78
|
+
$username = $lib.null
|
|
79
|
+
if (not $user) {
|
|
80
|
+
$username = `User not found ({$mdef.creator})`
|
|
81
|
+
} else {
|
|
82
|
+
$username = $user.name
|
|
83
|
+
}
|
|
84
|
+
$lib.print('{name} (owner: {user})', name=$name.ljust(20), user=$username)
|
|
79
85
|
$count = $($count + 1)
|
|
80
86
|
}
|
|
81
87
|
$lib.print('{count} macros found', count=$count)
|
|
@@ -185,27 +191,17 @@ class LibMacro(s_stormtypes.Lib):
|
|
|
185
191
|
async def _funcMacroGet(self, name):
|
|
186
192
|
name = await s_stormtypes.tostr(name)
|
|
187
193
|
|
|
188
|
-
if len(name) > 491:
|
|
189
|
-
raise s_exc.BadArg(mesg='Macro names may only be up to 491 chars.')
|
|
190
|
-
|
|
191
194
|
return self.runt.snap.core.getStormMacro(name, user=self.runt.user)
|
|
192
195
|
|
|
193
196
|
async def _funcMacroDel(self, name):
|
|
194
|
-
|
|
195
197
|
name = await s_stormtypes.tostr(name)
|
|
196
198
|
|
|
197
|
-
if len(name) > 491:
|
|
198
|
-
raise s_exc.BadArg(mesg='Macro names may only be up to 491 chars.')
|
|
199
|
-
|
|
200
199
|
return await self.runt.snap.core.delStormMacro(name, user=self.runt.user)
|
|
201
200
|
|
|
202
201
|
async def _funcMacroSet(self, name, storm):
|
|
203
202
|
name = await s_stormtypes.tostr(name)
|
|
204
203
|
storm = await s_stormtypes.tostr(storm)
|
|
205
204
|
|
|
206
|
-
if len(name) > 491:
|
|
207
|
-
raise s_exc.BadArg(mesg='Macro names may only be up to 491 chars.')
|
|
208
|
-
|
|
209
205
|
await self.runt.getStormQuery(storm)
|
|
210
206
|
|
|
211
207
|
if self.runt.snap.core.getStormMacro(name) is None:
|
|
@@ -220,9 +216,6 @@ class LibMacro(s_stormtypes.Lib):
|
|
|
220
216
|
name = await s_stormtypes.tostr(name)
|
|
221
217
|
info = await s_stormtypes.toprim(info)
|
|
222
218
|
|
|
223
|
-
if len(name) > 491:
|
|
224
|
-
raise s_exc.BadArg(mesg='Macro names may only be up to 491 chars.')
|
|
225
|
-
|
|
226
219
|
if not isinstance(info, dict):
|
|
227
220
|
raise s_exc.BadArg(mesg='Macro info must be a dictionary object.')
|
|
228
221
|
|
synapse/lib/stormlib/stix.py
CHANGED
|
@@ -585,7 +585,7 @@ def validateStix(bundle, version='2.1'):
|
|
|
585
585
|
'result': {},
|
|
586
586
|
}
|
|
587
587
|
bundle = json.loads(json.dumps(bundle))
|
|
588
|
-
opts = stix2validator.ValidationOptions(strict=True, version=version
|
|
588
|
+
opts = stix2validator.ValidationOptions(strict=True, version=version)
|
|
589
589
|
try:
|
|
590
590
|
results = stix2validator.validate_parsed_json(bundle, options=opts)
|
|
591
591
|
except stix2validator.ValidationError as e:
|
synapse/lib/stormtypes.py
CHANGED
|
@@ -1707,6 +1707,13 @@ class LibDict(Lib):
|
|
|
1707
1707
|
A Storm Library for interacting with dictionaries.
|
|
1708
1708
|
'''
|
|
1709
1709
|
_storm_locals = (
|
|
1710
|
+
{'name': 'has', 'desc': 'Check a dictionary has a specific key.',
|
|
1711
|
+
'type': {'type': 'function', '_funcname': '_has',
|
|
1712
|
+
'args': (
|
|
1713
|
+
{'name': 'valu', 'type': 'dict', 'desc': 'The dictionary being checked.'},
|
|
1714
|
+
{'name': 'name', 'type': 'str', 'desc': 'The key name to check.'},
|
|
1715
|
+
),
|
|
1716
|
+
'returns': {'type': 'boolean', 'desc': 'True if the key is present, false if the key is not present.'}}},
|
|
1710
1717
|
{'name': 'keys', 'desc': 'Retrieve a list of keys in the specified dictionary.',
|
|
1711
1718
|
'type': {'type': 'function', '_funcname': '_keys',
|
|
1712
1719
|
'args': (
|
|
@@ -3936,7 +3943,13 @@ class LibTelepath(Lib):
|
|
|
3936
3943
|
scheme = url.split('://')[0]
|
|
3937
3944
|
if not self.runt.allowed(('lib', 'telepath', 'open', scheme)):
|
|
3938
3945
|
self.runt.confirm(('storm', 'lib', 'telepath', 'open', scheme))
|
|
3939
|
-
|
|
3946
|
+
try:
|
|
3947
|
+
return Proxy(self.runt, await self.runt.getTeleProxy(url))
|
|
3948
|
+
except s_exc.SynErr:
|
|
3949
|
+
raise
|
|
3950
|
+
except Exception as e:
|
|
3951
|
+
mesg = f'Failed to connect to Telepath service: "{s_urlhelp.sanitizeUrl(url)}" error: {str(e)}'
|
|
3952
|
+
raise s_exc.StormRuntimeError(mesg=mesg) from e
|
|
3940
3953
|
|
|
3941
3954
|
@registry.registerType
|
|
3942
3955
|
class Proxy(StormType):
|
|
@@ -7382,7 +7395,11 @@ class View(Prim):
|
|
|
7382
7395
|
The parent View iden.
|
|
7383
7396
|
|
|
7384
7397
|
nomerge (bool)
|
|
7385
|
-
|
|
7398
|
+
Deprecated - use protected. Updates to this option will be redirected to
|
|
7399
|
+
the protected option (below) until this option is removed.
|
|
7400
|
+
|
|
7401
|
+
protected (bool)
|
|
7402
|
+
Setting to $lib.true will prevent the layer from being merged or deleted.
|
|
7386
7403
|
|
|
7387
7404
|
layers (list(str))
|
|
7388
7405
|
Set the list of layer idens for a non-forked view. Layers are specified
|
|
@@ -7781,6 +7798,8 @@ class View(Prim):
|
|
|
7781
7798
|
|
|
7782
7799
|
@stormfunc(readonly=True)
|
|
7783
7800
|
async def _methViewGet(self, name, defv=None):
|
|
7801
|
+
if name == 'nomerge':
|
|
7802
|
+
name = 'protected'
|
|
7784
7803
|
return self.valu.get(name, defv)
|
|
7785
7804
|
|
|
7786
7805
|
def _reqView(self):
|
|
@@ -7807,6 +7826,10 @@ class View(Prim):
|
|
|
7807
7826
|
valu = await toprim(valu)
|
|
7808
7827
|
|
|
7809
7828
|
elif name == 'nomerge':
|
|
7829
|
+
name = 'protected'
|
|
7830
|
+
valu = await tobool(valu)
|
|
7831
|
+
|
|
7832
|
+
elif name == 'protected':
|
|
7810
7833
|
valu = await tobool(valu)
|
|
7811
7834
|
|
|
7812
7835
|
elif name == 'layers':
|
synapse/lib/types.py
CHANGED
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, 168, 0)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
228
|
+
commit = 'd07eb2560a6e5e025ce9c20efaafe5571a55856c'
|