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.

Files changed (53) hide show
  1. synapse/axon.py +4 -10
  2. synapse/cortex.py +55 -12
  3. synapse/exc.py +1 -0
  4. synapse/lib/aha.py +4 -1
  5. synapse/lib/base.py +11 -4
  6. synapse/lib/cell.py +11 -2
  7. synapse/lib/hive.py +11 -0
  8. synapse/lib/layer.py +2 -0
  9. synapse/lib/modelrev.py +6 -0
  10. synapse/lib/modules.py +1 -0
  11. synapse/lib/node.py +4 -2
  12. synapse/lib/schemas.py +1 -1
  13. synapse/lib/stormlib/aha.py +385 -20
  14. synapse/lib/stormlib/easyperm.py +8 -0
  15. synapse/lib/stormlib/macro.py +11 -18
  16. synapse/lib/stormlib/stix.py +1 -1
  17. synapse/lib/stormtypes.py +25 -2
  18. synapse/lib/types.py +2 -0
  19. synapse/lib/version.py +2 -2
  20. synapse/lib/view.py +5 -3
  21. synapse/models/base.py +8 -0
  22. synapse/models/files.py +3 -0
  23. synapse/models/planning.py +161 -0
  24. synapse/telepath.py +1 -0
  25. synapse/tests/files/stormpkg/dotstorm/dotstorm.yaml +3 -0
  26. synapse/tests/test_cortex.py +40 -3
  27. synapse/tests/test_lib_aha.py +8 -4
  28. synapse/tests/test_lib_cell.py +6 -2
  29. synapse/tests/test_lib_grammar.py +62 -64
  30. synapse/tests/test_lib_httpapi.py +1 -1
  31. synapse/tests/test_lib_rstorm.py +4 -4
  32. synapse/tests/test_lib_storm.py +3 -3
  33. synapse/tests/test_lib_stormlib_aha.py +196 -0
  34. synapse/tests/test_lib_stormlib_compression.py +12 -12
  35. synapse/tests/test_lib_stormlib_macro.py +94 -0
  36. synapse/tests/test_lib_stormlib_spooled.py +1 -1
  37. synapse/tests/test_lib_stormtypes.py +44 -33
  38. synapse/tests/test_lib_trigger.py +3 -3
  39. synapse/tests/test_lib_view.py +50 -3
  40. synapse/tests/test_model_files.py +3 -0
  41. synapse/tests/test_model_planning.py +126 -0
  42. synapse/tests/test_tools_genpkg.py +26 -0
  43. synapse/tests/test_tools_hiveload.py +1 -0
  44. synapse/tests/test_tools_hivesave.py +1 -0
  45. synapse/tests/utils.py +22 -3
  46. synapse/tools/autodoc.py +1 -1
  47. synapse/tools/hive/load.py +3 -0
  48. synapse/tools/hive/save.py +3 -0
  49. {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/METADATA +3 -3
  50. {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/RECORD +53 -50
  51. {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/LICENSE +0 -0
  52. {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/WHEEL +0 -0
  53. {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/top_level.txt +0 -0
@@ -1,43 +1,169 @@
1
- import synapse.common as s_common
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.add,
14
- 'del': self._del,
15
- 'get': self.get,
16
- 'list': self.list,
136
+ 'add': self._methPoolAdd,
137
+ 'del': self._methPoolDel,
138
+ 'get': self._methPoolGet,
139
+ 'list': self._methPoolList,
17
140
  }
18
141
 
19
- async def add(self, name):
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 _del(self, name):
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
- async def get(self, name):
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 list(self):
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.add,
61
- 'del': self._del,
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 add(self, svcname):
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 _del(self, svcname):
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 = await proxy.getAhaPool(poolname)
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 serivce pool named: {$cmdopts.poolname}`) }
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 serivce pool named: {$cmdopts.poolname}`) }
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
- $pool.del($cmdopts.svcname)
167
- $lib.print(`AHA service ({$cmdopts.svcname}) removed from service pool ({$pool.name})`)
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
  )
@@ -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
 
@@ -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.user)
78
- $lib.print('{name} (owner: {user})', name=$name.ljust(20), user=$user.name)
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
 
@@ -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, no_cache=True)
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
- return Proxy(self.runt, await self.runt.getTeleProxy(url))
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
- Setting to $lib.true will prevent the layer from being merged.
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
@@ -1447,6 +1447,8 @@ class Edge(Type):
1447
1447
 
1448
1448
  def postTypeInit(self):
1449
1449
 
1450
+ self.deprecated = True
1451
+
1450
1452
  self.fieldoffs = {'n1': 0, 'n2': 1}
1451
1453
 
1452
1454
  self.ndeftype = self.modl.types.get('ndef') # type: Ndef
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, 166, 0)
226
+ version = (2, 168, 0)
227
227
  verstring = '.'.join([str(x) for x in version])
228
- commit = '09f8a7b3ad1f2ed5949e7d1a9dc7d17161fab932'
228
+ commit = 'd07eb2560a6e5e025ce9c20efaafe5571a55856c'