synapse 2.222.0__py311-none-any.whl → 2.224.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 (49) hide show
  1. synapse/common.py +2 -2
  2. synapse/cortex.py +159 -31
  3. synapse/cryotank.py +1 -1
  4. synapse/datamodel.py +1 -1
  5. synapse/lib/ast.py +5 -3
  6. synapse/lib/layer.py +6 -6
  7. synapse/lib/nexus.py +1 -1
  8. synapse/lib/schemas.py +2 -0
  9. synapse/lib/snap.py +15 -9
  10. synapse/lib/storm.py +35 -191
  11. synapse/lib/stormlib/auth.py +1 -1
  12. synapse/lib/stormlib/imap.py +12 -4
  13. synapse/lib/stormlib/mime.py +15 -5
  14. synapse/lib/stormlib/pkg.py +598 -0
  15. synapse/lib/stormlib/task.py +114 -0
  16. synapse/lib/stormtypes.py +43 -175
  17. synapse/lib/trigger.py +16 -14
  18. synapse/lib/version.py +2 -2
  19. synapse/lib/view.py +17 -14
  20. synapse/models/files.py +1 -1
  21. synapse/models/inet.py +25 -0
  22. synapse/models/proj.py +3 -0
  23. synapse/models/risk.py +6 -0
  24. synapse/models/syn.py +8 -0
  25. synapse/tests/test_common.py +4 -0
  26. synapse/tests/test_cortex.py +52 -1
  27. synapse/tests/test_lib_aha.py +68 -53
  28. synapse/tests/test_lib_ast.py +3 -0
  29. synapse/tests/test_lib_cell.py +12 -12
  30. synapse/tests/test_lib_storm.py +128 -248
  31. synapse/tests/test_lib_stormlib_imap.py +14 -0
  32. synapse/tests/test_lib_stormlib_mime.py +24 -0
  33. synapse/tests/test_lib_stormlib_pkg.py +456 -0
  34. synapse/tests/test_lib_stormlib_task.py +98 -0
  35. synapse/tests/test_lib_stormtypes.py +12 -100
  36. synapse/tests/test_lib_trigger.py +66 -3
  37. synapse/tests/test_lib_view.py +53 -0
  38. synapse/tests/test_model_files.py +11 -0
  39. synapse/tests/test_model_inet.py +23 -0
  40. synapse/tests/test_model_proj.py +3 -1
  41. synapse/tests/test_model_risk.py +10 -0
  42. synapse/tests/test_model_syn.py +54 -2
  43. synapse/tools/cryo/cat.py +2 -1
  44. synapse/tools/cryo/list.py +2 -0
  45. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/METADATA +1 -1
  46. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/RECORD +49 -45
  47. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/WHEEL +0 -0
  48. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/licenses/LICENSE +0 -0
  49. {synapse-2.222.0.dist-info → synapse-2.224.0.dist-info}/top_level.txt +0 -0
@@ -8,7 +8,7 @@ import synapse.tools.backup as s_tools_backup
8
8
 
9
9
  class TrigTest(s_t_utils.SynTest):
10
10
 
11
- async def test_trigger_async(self):
11
+ async def test_trigger_async_base(self):
12
12
 
13
13
  with self.getTestDir() as dirn:
14
14
 
@@ -49,6 +49,24 @@ class TrigTest(s_t_utils.SynTest):
49
49
  self.none(nodes[0].tags.get('foo'))
50
50
  self.none(await core.callStorm('return($lib.queue.gen(foo).pop())'))
51
51
 
52
+ q = '''$u=$lib.auth.users.get($auto.opts.user)
53
+ $s=`f={$auto.opts.form} v={$auto.opts.valu} u={$u.name}`
54
+ $lib.log.info($s) [ test:guid="*" +#nodeadd]'''
55
+ tdef = {'cond': 'node:add', 'form': 'test:str', 'storm': q}
56
+ await core.view.addTrigger(tdef)
57
+ with self.getAsyncLoggerStream('synapse.storm.log', 'f=') as stream:
58
+ await core.nodes('[ test:str=foo ]')
59
+ self.true(await stream.wait(12))
60
+ self.eq(stream.getvalue().strip(), 'f=test:str v=foo u=root')
61
+ self.len(1, await core.nodes('test:guid#nodeadd'))
62
+ unfo = await core.addUser('someuser')
63
+ await core.setUserAdmin(unfo.get('iden'), True)
64
+ with self.getAsyncLoggerStream('synapse.storm.log', 'f=') as stream:
65
+ await core.nodes('[ test:str=bar ]', opts={'user': unfo.get('iden')})
66
+ self.true(await stream.wait(12))
67
+ self.eq(stream.getvalue().strip(), 'f=test:str v=bar u=someuser')
68
+ self.len(2, await core.nodes('test:guid#nodeadd'))
69
+
52
70
  async with self.getTestCore(dirn=dirn) as core:
53
71
 
54
72
  self.nn(await core.callStorm('return($lib.queue.gen(foo).pop(wait=$lib.true))'))
@@ -141,13 +159,15 @@ class TrigTest(s_t_utils.SynTest):
141
159
  view = core.view
142
160
 
143
161
  # node:add case
144
- q = '$s=`f={$auto.opts.form} v={$auto.opts.valu}` $lib.log.info($s) [ test:guid="*" +#nodeadd]'
162
+ q = '''$u=$lib.auth.users.get($auto.opts.user)
163
+ $s=`f={$auto.opts.form} v={$auto.opts.valu} u={$u.name}`
164
+ $lib.log.info($s) [ test:guid="*" +#nodeadd]'''
145
165
  tdef = {'cond': 'node:add', 'form': 'test:str', 'storm': q}
146
166
  await view.addTrigger(tdef)
147
167
  with self.getAsyncLoggerStream('synapse.storm.log', 'f=') as stream:
148
168
  await core.nodes('[ test:str=foo ]')
149
169
  self.true(await stream.wait(6))
150
- self.eq(stream.getvalue().strip(), 'f=test:str v=foo')
170
+ self.eq(stream.getvalue().strip(), 'f=test:str v=foo u=root')
151
171
  self.len(1, await core.nodes('test:guid#nodeadd'))
152
172
 
153
173
  # node:del case
@@ -910,3 +930,46 @@ class TrigTest(s_t_utils.SynTest):
910
930
  for view in core.views.values():
911
931
  for _, trigger in view.triggers.list():
912
932
  self.eq(trigger.tdef.get('view'), view.iden)
933
+
934
+ async def test_trigger_feed_data(self):
935
+ async with self.getTestCore() as core0:
936
+
937
+ podes = []
938
+
939
+ node1 = (await core0.nodes('[ test:int=1 ]'))[0]
940
+ await node1.setData('foo', 'bar')
941
+ pack = node1.pack()
942
+ pack[1]['nodedata']['foo'] = 'bar'
943
+ podes.append(pack)
944
+
945
+ node2 = (await core0.nodes('[ test:int=2 ] | [ +(refs)> { test:int=1 } ]'))[0]
946
+ pack = node2.pack()
947
+ pack[1]['edges'] = (('refs', node1.iden()), )
948
+ podes.append(pack)
949
+
950
+ node3 = (await core0.nodes('[ test:int=3 ]'))[0]
951
+ podes.append(node3.pack())
952
+
953
+ node = (await core0.nodes(f'[ test:int=4 ]'))[0]
954
+ pack = node.pack()
955
+ podes.append(pack)
956
+
957
+ async with self.getTestCore() as core1:
958
+
959
+ q = '''$u=$lib.auth.users.get($auto.opts.user)
960
+ $s=`f={$auto.opts.form} v={$auto.opts.valu} u={$u.name}`
961
+ $lib.log.info($s) [ test:guid="*" +#nodeadd]'''
962
+ tdef = {'cond': 'node:add', 'form': 'test:str', 'storm': q}
963
+ await core1.view.addTrigger(tdef)
964
+ tdef = {'cond': 'node:add', 'form': 'test:int', 'storm': q}
965
+ await core1.view.addTrigger(tdef)
966
+
967
+ with self.getAsyncLoggerStream('synapse.storm.log', 'f=') as stream:
968
+ await core1.addFeedData('syn.nodes', podes)
969
+ self.true(await stream.wait(6))
970
+ valu = stream.getvalue().strip()
971
+ self.isin('f=test:int v=1 u=root', valu)
972
+ self.isin('f=test:int v=2 u=root', valu)
973
+ self.isin('f=test:int v=3 u=root', valu)
974
+ self.isin('f=test:int v=4 u=root', valu)
975
+ self.len(4, await core1.nodes('test:guid#nodeadd'))
@@ -605,6 +605,59 @@ class ViewTest(s_t_utils.SynTest):
605
605
  self.len(1, await core.nodes('ou:org#foo', opts={'view': view}))
606
606
  self.len(1, await core.nodes('test:str=foo', opts={'view': view}))
607
607
 
608
+ async def test_lib_view_savenodeedits_telepath(self):
609
+
610
+ async with self.getTestCore() as core:
611
+
612
+ unfo = await core.getUserDefByName('root')
613
+ root = unfo.get('iden')
614
+
615
+ view = await core.callStorm('''
616
+ $layr = $lib.layer.add().iden
617
+ $view = $lib.view.add(($layr,))
618
+ return($view.iden)
619
+ ''')
620
+
621
+ await core.nodes('trigger.add node:add --form test:guid --query {$lib.log.info(`u={$auto.opts.user}`) [+#foo]}', opts={'view': view})
622
+ await core.nodes('trigger.add node:del --form test:int --query {$lib.log.info(`u={$auto.opts.user}`) [test:str=foo]}', opts={'view': view})
623
+
624
+ await core.nodes('[ test:guid=* ]')
625
+ self.len(0, await core.nodes('test:guid', opts={'view': view}))
626
+
627
+ await core.nodes('[ test:int=0 ]')
628
+ self.len(0, await core.nodes('test:int', opts={'view': view}))
629
+
630
+ await core.nodes('test:int | delnode')
631
+
632
+ edits = await core.callStorm('''$nodeedits = ()
633
+ for ($offs, $edits) in $lib.layer.get().edits(wait=$lib.false) {
634
+ $nodeedits.extend($edits)
635
+ }
636
+ return($nodeedits)''')
637
+
638
+ user = await core.auth.addUser('user')
639
+ await user.addRule((True, ('view', 'read')))
640
+ guid = s_common.guid()
641
+
642
+ async with core.getLocalProxy(share=f'*/view/{view}', user='user') as prox:
643
+ with self.raises(s_exc.AuthDeny):
644
+ await prox.saveNodeEdits(edits, {})
645
+
646
+ await core.setUserAdmin(user.iden, True)
647
+
648
+ with self.raises(s_exc.BadArg) as cm:
649
+ await prox.saveNodeEdits(edits, {})
650
+ self.eq(cm.exception.get('mesg'), "Meta argument requires user key to be a guid, got user=''")
651
+
652
+ with self.getAsyncLoggerStream('synapse.storm.log', 'u=') as stream:
653
+ await prox.saveNodeEdits(edits, {'time': s_common.now(), 'user': guid})
654
+ self.true(await stream.wait(6))
655
+ valu = stream.getvalue().strip()
656
+ self.isin(f'u={guid}', valu)
657
+
658
+ self.len(1, await core.nodes('test:guid#foo', opts={'view': view}))
659
+ self.len(1, await core.nodes('test:str=foo', opts={'view': view}))
660
+
608
661
  async def test_lib_view_wipeLayer(self):
609
662
 
610
663
  async with self.getTestCore() as core:
@@ -103,6 +103,17 @@ class FileTest(s_t_utils.SynTest):
103
103
  self.eq(rnode.get('type'), 2)
104
104
  self.eq(rnode.repr('langid'), 'en-US')
105
105
  self.eq(rnode.repr('type'), 'RT_BITMAP')
106
+ # unknown langid
107
+ nodes = await core.nodes('[file:mime:pe:resource=$valu]',
108
+ opts={'vars': {'valu': (filea, 2, 0x1804, 'd' * 64)}})
109
+ self.len(1, nodes)
110
+ rnode = nodes[0]
111
+ self.eq(rnode.get('langid'), 0x1804)
112
+ self.eq(rnode.repr('langid'), '6148')
113
+ # invalid langid
114
+ with self.raises(s_exc.BadTypeValu):
115
+ await core.nodes('[file:mime:pe:resource=$valu]',
116
+ opts={'vars': {'valu': (filea, 2, 0xfffff, 'd' * 64)}})
106
117
  # pe section
107
118
  nodes = await core.nodes('[file:mime:pe:section=$valu]',
108
119
  opts={'vars': {'valu': (filea, 'foo', 'b' * 64)}})
@@ -2991,10 +2991,17 @@ class InetModelTest(s_t_utils.SynTest):
2991
2991
 
2992
2992
  q = '''
2993
2993
  [ inet:service:platform=(slack,)
2994
+ :id=foo
2994
2995
  :url="https://slack.com"
2995
2996
  :urls=(https://slacker.com,)
2997
+ :zones=(slack.com, slacker.com)
2996
2998
  :name=Slack
2997
2999
  :names=("slack chat",)
3000
+ :parent={[ inet:service:platform=({"name": "salesforce"}) ]}
3001
+ :status=available
3002
+ :period=(2022, 2023)
3003
+ :creator={[ inet:service:account=({"id": "bar"}) ]}
3004
+ :remover={[ inet:service:account=({"id": "baz"}) ]}
2998
3005
  :provider={ ou:org:name=$provname }
2999
3006
  :provider:name=$provname
3000
3007
  ]
@@ -3002,20 +3009,36 @@ class InetModelTest(s_t_utils.SynTest):
3002
3009
  nodes = await core.nodes(q, opts=opts)
3003
3010
  self.len(1, nodes)
3004
3011
  self.eq(nodes[0].ndef, ('inet:service:platform', s_common.guid(('slack',))))
3012
+ self.eq('foo', nodes[0].get('id'))
3005
3013
  self.eq(nodes[0].get('url'), 'https://slack.com')
3006
3014
  self.eq(nodes[0].get('urls'), ('https://slacker.com',))
3015
+ self.eq(nodes[0].get('zones'), ('slack.com', 'slacker.com'))
3007
3016
  self.eq(nodes[0].get('name'), 'slack')
3008
3017
  self.eq(nodes[0].get('names'), ('slack chat',))
3018
+ self.eq(nodes[0].repr('status'), 'available')
3019
+ self.eq(nodes[0].repr('period'), ('2022/01/01 00:00:00.000', '2023/01/01 00:00:00.000'))
3009
3020
  self.eq(nodes[0].get('provider'), provider.ndef[1])
3010
3021
  self.eq(nodes[0].get('provider:name'), provname.lower())
3011
3022
  platform = nodes[0]
3012
3023
 
3024
+ nodes = await core.nodes('inet:service:platform=(slack,) :parent -> *')
3025
+ self.eq(['salesforce'], [n.get('name') for n in nodes])
3026
+
3027
+ nodes = await core.nodes('inet:service:platform=(slack,) :creator -> *')
3028
+ self.eq(['bar'], [n.get('id') for n in nodes])
3029
+
3030
+ nodes = await core.nodes('inet:service:platform=(slack,) :remover -> *')
3031
+ self.eq(['baz'], [n.get('id') for n in nodes])
3032
+
3013
3033
  nodes = await core.nodes('[ inet:service:platform=({"name": "slack chat"}) ]')
3014
3034
  self.eq(nodes[0].ndef, platform.ndef)
3015
3035
 
3016
3036
  nodes = await core.nodes('[ inet:service:platform=({"url": "https://slacker.com"}) ]')
3017
3037
  self.eq(nodes[0].ndef, platform.ndef)
3018
3038
 
3039
+ nodes = await core.nodes('[ inet:service:platform=({"zone": "slacker.com"}) ]')
3040
+ self.eq(nodes[0].ndef, platform.ndef)
3041
+
3019
3042
  q = '''
3020
3043
  [ inet:service:instance=(vertex, slack)
3021
3044
  :id='T2XK1223Y'
@@ -1,4 +1,5 @@
1
1
  import synapse.exc as s_exc
2
+ import synapse.common as s_common
2
3
  import synapse.tests.utils as s_test
3
4
 
4
5
  class ProjModelTest(s_test.SynTest):
@@ -256,13 +257,14 @@ class ProjModelTest(s_test.SynTest):
256
257
  self.eq('highest', nodes[0].repr('priority'))
257
258
  self.eq(proj, nodes[0].get('project'))
258
259
 
259
- nodes = await core.nodes('proj:comment')
260
+ nodes = await core.nodes('proj:comment [ :ext:creator={[ps:contact=(visi,) :name=visi ]} ]')
260
261
  self.len(1, nodes)
261
262
  self.nn(nodes[0].get('created'))
262
263
  self.nn(nodes[0].get('updated'))
263
264
  self.eq(tick, nodes[0].get('ticket'))
264
265
  self.eq('hithere', nodes[0].get('text'))
265
266
  self.eq(visi.iden, nodes[0].get('creator'))
267
+ self.eq(s_common.guid(('visi',)), nodes[0].get('ext:creator'))
266
268
 
267
269
  self.eq('foo', await core.callStorm('return($lib.projects.get($proj).name)', opts=opts))
268
270
  self.eq('bar', await core.callStorm('return($lib.projects.get($proj).epics.get($epic).name)', opts=opts))
@@ -3,6 +3,7 @@ import logging
3
3
  import synapse.exc as s_exc
4
4
  import synapse.common as s_common
5
5
  import synapse.lib.chop as s_chop
6
+ import synapse.lib.time as s_time
6
7
  import synapse.tests.utils as s_t_utils
7
8
 
8
9
  logger = logging.getLogger(__name__)
@@ -325,6 +326,15 @@ class RiskModelTest(s_t_utils.SynTest):
325
326
  self.len(1, await core.nodes('risk:alert :service:platform -> inet:service:platform'))
326
327
  self.len(1, await core.nodes('risk:alert :service:instance -> inet:service:instance'))
327
328
 
329
+ opts = {'vars': {'ndef': nodes[0].ndef[1]}}
330
+ nodes = await core.nodes('risk:alert=$ndef [ :updated=20251003 ]', opts=opts)
331
+ self.len(1, nodes)
332
+ self.eq(s_time.parse('20251003'), nodes[0].get('updated'))
333
+
334
+ self.len(1, await core.nodes('[ risk:alert=({"name": "bazfaz"}) +(about)> {[ file:bytes=* :name=alert.txt]} ]'))
335
+ self.len(1, fnode := await core.nodes('risk:alert=({"name": "bazfaz"}) -(about)> file:bytes'))
336
+ self.eq(fnode[0].get('name'), 'alert.txt')
337
+
328
338
  nodes = await core.nodes('''[
329
339
  risk:compromise=*
330
340
  :vector=*
@@ -1,8 +1,9 @@
1
1
  import synapse.exc as s_exc
2
2
  import synapse.common as s_common
3
3
  import synapse.cortex as s_cortex
4
- import synapse.datamodel as s_datamodel
5
4
 
5
+ import synapse.lib.time as s_time
6
+ import synapse.lib.version as s_version
6
7
  import synapse.lib.stormsvc as s_stormsvc
7
8
 
8
9
  import synapse.tests.utils as s_t_utils
@@ -42,6 +43,21 @@ class TestService(s_stormsvc.StormSvc):
42
43
  },
43
44
  'storm': '',
44
45
  },
46
+ {
47
+ 'name': 'deprvers',
48
+ 'storm': '',
49
+ 'deprecated': {'eolvers': 'v3.0.0'},
50
+ },
51
+ {
52
+ 'name': 'deprdate',
53
+ 'storm': '',
54
+ 'deprecated': {'eoldate': '2099-01-01'},
55
+ },
56
+ {
57
+ 'name': 'deprmesg',
58
+ 'storm': '',
59
+ 'deprecated': {'eoldate': '2099-01-01', 'mesg': 'Please use ``ohhai``.'},
60
+ },
45
61
  )
46
62
  },
47
63
  )
@@ -683,7 +699,7 @@ class SynModelTest(s_t_utils.SynTest):
683
699
 
684
700
  # check that runt nodes for new commands are created
685
701
  nodes = await core.nodes('syn:cmd +:package')
686
- self.len(2, nodes)
702
+ self.len(5, nodes)
687
703
 
688
704
  self.eq(nodes[0].ndef, ('syn:cmd', 'foobar'))
689
705
  self.eq(nodes[0].get('doc'), 'foobar is a great service')
@@ -692,6 +708,7 @@ class SynModelTest(s_t_utils.SynTest):
692
708
  self.eq(nodes[0].get('nodedata'), (('foo', 'inet:ipv4'), ('bar', 'inet:fqdn')))
693
709
  self.eq(nodes[0].get('package'), 'foo')
694
710
  self.eq(nodes[0].get('svciden'), iden)
711
+ self.none(nodes[0].get('deprecated'))
695
712
 
696
713
  self.eq(nodes[1].ndef, ('syn:cmd', 'ohhai'))
697
714
  self.eq(nodes[1].get('doc'), 'No description')
@@ -700,6 +717,41 @@ class SynModelTest(s_t_utils.SynTest):
700
717
  self.none(nodes[1].get('nodedata'))
701
718
  self.eq(nodes[1].get('package'), 'foo')
702
719
  self.eq(nodes[1].get('svciden'), iden)
720
+ self.none(nodes[1].get('deprecated'))
721
+
722
+ self.eq(nodes[2].ndef, ('syn:cmd', 'deprvers'))
723
+ self.true(nodes[2].get('deprecated'))
724
+ self.eq(nodes[2].get('deprecated:version'), s_version.packVersion(3, 0, 0))
725
+ self.none(nodes[2].get('deprecated:date'))
726
+ self.none(nodes[2].get('deprecated:mesg'))
727
+
728
+ self.eq(nodes[3].ndef, ('syn:cmd', 'deprdate'))
729
+ self.true(nodes[3].get('deprecated'))
730
+ self.none(nodes[3].get('deprecated:version'))
731
+ self.eq(nodes[3].get('deprecated:date'), s_time.parse('2099-01-01'))
732
+ self.none(nodes[3].get('deprecated:mesg'))
733
+
734
+ self.eq(nodes[4].ndef, ('syn:cmd', 'deprmesg'))
735
+ self.true(nodes[4].get('deprecated'))
736
+ self.none(nodes[4].get('deprecated:version'))
737
+ self.eq(nodes[4].get('deprecated:date'), s_time.parse('2099-01-01'))
738
+ self.eq(nodes[4].get('deprecated:mesg'), 'Please use ``ohhai``.')
739
+
740
+ nodes = await core.nodes('syn:cmd:deprecated')
741
+ self.len(5, nodes)
742
+ self.sorteq(['deprvers', 'deprdate', 'deprmesg', 'ps.list', 'ps.kill'], [k.ndef[1] for k in nodes])
743
+
744
+ nodes = await core.nodes('syn:cmd:deprecated:version')
745
+ self.len(3, nodes)
746
+ self.sorteq(['deprvers', 'ps.list', 'ps.kill'], [k.ndef[1] for k in nodes])
747
+
748
+ nodes = await core.nodes('syn:cmd:deprecated:date')
749
+ self.len(2, nodes)
750
+ self.sorteq(['deprdate', 'deprmesg'], [k.ndef[1] for k in nodes])
751
+
752
+ nodes = await core.nodes('syn:cmd:deprecated:mesg')
753
+ self.len(3, nodes)
754
+ self.sorteq(['deprmesg', 'ps.list', 'ps.kill'], [k.ndef[1] for k in nodes])
703
755
 
704
756
  # Pivot from cmds to their forms
705
757
  nodes = await core.nodes('syn:cmd=foobar -> *')
synapse/tools/cryo/cat.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import sys
2
2
  import pprint
3
- import argparse
4
3
 
4
+ import synapse.common as s_common
5
5
  import synapse.telepath as s_telepath
6
6
 
7
7
  import synapse.lib.cmd as s_cmd
@@ -58,4 +58,5 @@ async def main(argv, outp=s_output.stdout):
58
58
  return 0
59
59
 
60
60
  if __name__ == '__main__': # pragma: no cover
61
+ s_common.deprecated('synapse.tools.cryo.cat', curv='2.223.0')
61
62
  s_cmd.exitmain(main)
@@ -1,3 +1,4 @@
1
+ import synapse.common as s_common
1
2
  import synapse.telepath as s_telepath
2
3
 
3
4
  import synapse.lib.cmd as s_cmd
@@ -24,4 +25,5 @@ async def main(argv, outp=s_output.stdout):
24
25
  return 0
25
26
 
26
27
  if __name__ == '__main__': # pragma: no cover
28
+ s_common.deprecated('synapse.tools.cryo.list', curv='2.223.0')
27
29
  s_cmd.exitmain(main)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synapse
3
- Version: 2.222.0
3
+ Version: 2.224.0
4
4
  Summary: Synapse Intelligence Analysis Framework
5
5
  Author-email: The Vertex Project LLC <root@vertex.link>
6
6
  License-Expression: Apache-2.0