synapse 2.193.0__py311-none-any.whl → 2.194.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 (65) hide show
  1. synapse/cortex.py +3 -7
  2. synapse/datamodel.py +6 -3
  3. synapse/exc.py +1 -1
  4. synapse/lib/agenda.py +17 -4
  5. synapse/lib/ast.py +217 -86
  6. synapse/lib/auth.py +1 -0
  7. synapse/lib/parser.py +4 -0
  8. synapse/lib/snap.py +40 -11
  9. synapse/lib/storm.lark +16 -1
  10. synapse/lib/storm.py +6 -4
  11. synapse/lib/storm_format.py +1 -0
  12. synapse/lib/stormctrl.py +88 -6
  13. synapse/lib/stormlib/cache.py +6 -2
  14. synapse/lib/stormlib/scrape.py +1 -1
  15. synapse/lib/stormlib/stix.py +8 -8
  16. synapse/lib/stormtypes.py +13 -5
  17. synapse/lib/version.py +2 -2
  18. synapse/lib/view.py +20 -3
  19. synapse/models/geopol.py +1 -0
  20. synapse/models/geospace.py +1 -0
  21. synapse/models/inet.py +3 -0
  22. synapse/models/infotech.py +10 -2
  23. synapse/models/orgs.py +7 -2
  24. synapse/models/person.py +15 -4
  25. synapse/models/risk.py +3 -0
  26. synapse/models/telco.py +10 -3
  27. synapse/tests/test_axon.py +6 -6
  28. synapse/tests/test_cortex.py +130 -11
  29. synapse/tests/test_exc.py +1 -0
  30. synapse/tests/test_lib_agenda.py +125 -1
  31. synapse/tests/test_lib_aha.py +13 -6
  32. synapse/tests/test_lib_ast.py +258 -9
  33. synapse/tests/test_lib_auth.py +6 -7
  34. synapse/tests/test_lib_grammar.py +14 -0
  35. synapse/tests/test_lib_layer.py +1 -1
  36. synapse/tests/test_lib_lmdbslab.py +3 -3
  37. synapse/tests/test_lib_storm.py +201 -25
  38. synapse/tests/test_lib_stormctrl.py +65 -0
  39. synapse/tests/test_lib_stormhttp.py +5 -5
  40. synapse/tests/test_lib_stormlib_auth.py +5 -5
  41. synapse/tests/test_lib_stormlib_cache.py +38 -6
  42. synapse/tests/test_lib_stormlib_modelext.py +3 -3
  43. synapse/tests/test_lib_stormlib_scrape.py +4 -4
  44. synapse/tests/test_lib_stormlib_spooled.py +1 -1
  45. synapse/tests/test_lib_stormlib_xml.py +5 -5
  46. synapse/tests/test_lib_stormtypes.py +54 -57
  47. synapse/tests/test_lib_view.py +1 -1
  48. synapse/tests/test_model_base.py +1 -2
  49. synapse/tests/test_model_geopol.py +4 -0
  50. synapse/tests/test_model_geospace.py +6 -0
  51. synapse/tests/test_model_inet.py +3 -0
  52. synapse/tests/test_model_infotech.py +10 -1
  53. synapse/tests/test_model_orgs.py +17 -2
  54. synapse/tests/test_model_person.py +23 -1
  55. synapse/tests/test_model_risk.py +11 -0
  56. synapse/tests/test_tools_healthcheck.py +4 -4
  57. synapse/tests/test_utils.py +17 -18
  58. synapse/tests/utils.py +0 -35
  59. synapse/tools/changelog.py +6 -4
  60. synapse/tools/storm.py +1 -1
  61. {synapse-2.193.0.dist-info → synapse-2.194.0.dist-info}/METADATA +5 -5
  62. {synapse-2.193.0.dist-info → synapse-2.194.0.dist-info}/RECORD +65 -64
  63. {synapse-2.193.0.dist-info → synapse-2.194.0.dist-info}/WHEEL +1 -1
  64. {synapse-2.193.0.dist-info → synapse-2.194.0.dist-info}/LICENSE +0 -0
  65. {synapse-2.193.0.dist-info → synapse-2.194.0.dist-info}/top_level.txt +0 -0
synapse/models/person.py CHANGED
@@ -254,6 +254,7 @@ class PsModule(s_module.CoreModule):
254
254
  'doc': 'The most recent known vitals for the person.',
255
255
  }),
256
256
  ('name', ('ps:name', {}), {
257
+ 'alts': ('names',),
257
258
  'doc': 'The localized name for the person.',
258
259
  }),
259
260
  ('name:sur', ('ps:tokn', {}), {
@@ -350,12 +351,17 @@ class PsModule(s_module.CoreModule):
350
351
  'doc': 'The most recent known vitals for the contact.',
351
352
  }),
352
353
  ('name', ('ps:name', {}), {
353
- 'doc': 'The person name listed for the contact.',
354
- }),
354
+ 'alts': ('names',),
355
+ 'doc': 'The person name listed for the contact.'}),
356
+
357
+ ('bio', ('str', {}), {
358
+ 'doc': 'A brief bio provided for the contact.'}),
359
+
355
360
  ('desc', ('str', {}), {
356
- 'doc': 'A description of this contact.',
357
- }),
361
+ 'doc': 'A description of this contact.'}),
362
+
358
363
  ('title', ('ou:jobtitle', {}), {
364
+ 'alts': ('titles',),
359
365
  'doc': 'The job/org title listed for this contact.'}),
360
366
 
361
367
  ('titles', ('array', {'type': 'ou:jobtitle', 'sorted': True, 'uniq': True}), {
@@ -365,12 +371,14 @@ class PsModule(s_module.CoreModule):
365
371
  'doc': 'The photo listed for this contact.',
366
372
  }),
367
373
  ('orgname', ('ou:name', {}), {
374
+ 'alts': ('orgnames',),
368
375
  'doc': 'The listed org/company name for this contact.',
369
376
  }),
370
377
  ('orgfqdn', ('inet:fqdn', {}), {
371
378
  'doc': 'The listed org/company FQDN for this contact.',
372
379
  }),
373
380
  ('user', ('inet:user', {}), {
381
+ 'alts': ('users',),
374
382
  'doc': 'The username or handle for this contact.'}),
375
383
 
376
384
  ('service:accounts', ('array', {'type': 'inet:service:account', 'sorted': True, 'uniq': True}), {
@@ -412,6 +420,7 @@ class PsModule(s_module.CoreModule):
412
420
  'doc': 'The home or main site for this contact.',
413
421
  }),
414
422
  ('email', ('inet:email', {}), {
423
+ 'alts': ('emails',),
415
424
  'doc': 'The main email address for this contact.',
416
425
  }),
417
426
  ('email:work', ('inet:email', {}), {
@@ -440,6 +449,7 @@ class PsModule(s_module.CoreModule):
440
449
  'doc': 'The work phone number for this contact.',
441
450
  }),
442
451
  ('id:number', ('ou:id:number', {}), {
452
+ 'alts': ('id:numbers',),
443
453
  'doc': 'An ID number issued by an org and associated with this contact.',
444
454
  }),
445
455
  ('adid', ('it:adid', {}), {
@@ -479,6 +489,7 @@ class PsModule(s_module.CoreModule):
479
489
  }),
480
490
 
481
491
  ('lang', ('lang:language', {}), {
492
+ 'alts': ('langs',),
482
493
  'doc': 'The language specified for the contact.'}),
483
494
 
484
495
  ('langs', ('array', {'type': 'lang:language'}), {
synapse/models/risk.py CHANGED
@@ -310,6 +310,7 @@ class RiskModule(s_module.CoreModule):
310
310
  'doc': "The reporting organization's assessed location of the threat cluster."}),
311
311
 
312
312
  ('org:name', ('ou:name', {}), {
313
+ 'alts': ('org:names',),
313
314
  'ex': 'apt1',
314
315
  'doc': "The reporting organization's name for the threat cluster."}),
315
316
 
@@ -383,6 +384,7 @@ class RiskModule(s_module.CoreModule):
383
384
  'doc': 'The authoritative software family for the tool.'}),
384
385
 
385
386
  ('soft:name', ('it:prod:softname', {}), {
387
+ 'alts': ('soft:names',),
386
388
  'doc': 'The reporting organization\'s name for the tool.'}),
387
389
 
388
390
  ('soft:names', ('array', {'type': 'it:prod:softname', 'uniq': True, 'sorted': True}), {
@@ -441,6 +443,7 @@ class RiskModule(s_module.CoreModule):
441
443
  ('risk:vuln', {}, (
442
444
 
443
445
  ('name', ('risk:vulnname', {}), {
446
+ 'alts': ('names',),
444
447
  'doc': 'A user specified name for the vulnerability.'}),
445
448
 
446
449
  ('names', ('array', {'type': 'risk:vulnname', 'sorted': True, 'uniq': True}), {
synapse/models/telco.py CHANGED
@@ -369,9 +369,16 @@ class TelcoModule(s_module.CoreModule):
369
369
  ('wifi:bssid', ('inet:mac', {}), {}),
370
370
 
371
371
  # host specific data
372
- ('adid', ('it:adid', {}), {}),
373
- ('aaid', ('it:os:android:aaid', {}), {}),
374
- ('idfa', ('it:os:ios:idfa', {}), {}),
372
+ ('adid', ('it:adid', {}), {
373
+ 'doc': 'The advertising ID of the mobile telemetry sample.'}),
374
+
375
+ ('aaid', ('it:os:android:aaid', {}), {
376
+ 'deprecated': True,
377
+ 'doc': 'Deprecated. Please use :adid.'}),
378
+
379
+ ('idfa', ('it:os:ios:idfa', {}), {
380
+ 'deprecated': True,
381
+ 'doc': 'Deprecated. Please use :adid.'}),
375
382
 
376
383
  # User related data
377
384
  ('name', ('ps:name', {}), {}),
@@ -990,12 +990,12 @@ bar baz",vv
990
990
  self.isinstance(resp.get('err'), tuple)
991
991
 
992
992
  q = f'''
993
- $fields = $lib.list(
994
- ({{'name':'file', 'sha256':$sha256, 'filename':'file'}}),
995
- ({{'name':'zip_password', 'value':'test'}}),
996
- ({{'name':'dict', 'value':({{'foo':'bar'}}) }}),
997
- ({{'name':'bytes', 'value':$bytes}})
998
- )
993
+ $fields = ([
994
+ {{'name':'file', 'sha256':$sha256, 'filename':'file'}},
995
+ {{'name':'zip_password', 'value':'test'}},
996
+ {{'name':'dict', 'value':{{'foo':'bar'}} }},
997
+ {{'name':'bytes', 'value':$bytes}}
998
+ ])
999
999
  $resp = $lib.inet.http.post("https://127.0.0.1:{port}/api/v1/pushfile",
1000
1000
  fields=$fields, ssl_verify=(0))
1001
1001
  return($resp)
@@ -440,7 +440,7 @@ class CortexTest(s_t_utils.SynTest):
440
440
  'interfaces': ['lookup'],
441
441
  'storm': '''
442
442
  function lookup(tokens) {
443
- $looks = $lib.list()
443
+ $looks = ()
444
444
  for $token in $tokens { $looks.append( (inet:fqdn, $token) ) }
445
445
  return($looks)
446
446
  }
@@ -679,7 +679,7 @@ class CortexTest(s_t_utils.SynTest):
679
679
  # functions that don't return a generator
680
680
  storm = '''
681
681
  function x() {
682
- $lst = $lib.list()
682
+ $lst = ()
683
683
  [ ou:org=* ou:org=* +#cat ]
684
684
  $lst.append($node)
685
685
  fini { return($lst) }
@@ -692,7 +692,7 @@ class CortexTest(s_t_utils.SynTest):
692
692
 
693
693
  storm = '''
694
694
  function x() {
695
- $lst = $lib.list()
695
+ $lst = ()
696
696
  [ ou:org=* ou:org=* +#dog ]
697
697
  $lst.append($node)
698
698
  fini { return($lst) }
@@ -974,7 +974,7 @@ class CortexTest(s_t_utils.SynTest):
974
974
  await core.nodes('media:news -(refs)> $(10)')
975
975
 
976
976
  self.eq(1, await core.callStorm('''
977
- $list = $lib.list()
977
+ $list = ()
978
978
  for $edge in $lib.view.get().getEdges() { $list.append($edge) }
979
979
  return($list.size())
980
980
  '''))
@@ -982,7 +982,7 @@ class CortexTest(s_t_utils.SynTest):
982
982
  # check that auto-deleting a node's edges works
983
983
  await core.nodes('media:news | delnode')
984
984
  self.eq(0, await core.callStorm('''
985
- $list = $lib.list()
985
+ $list = ()
986
986
  for $edge in $lib.view.get().getEdges() { $list.append($edge) }
987
987
  return($list.size())
988
988
  '''))
@@ -1017,7 +1017,7 @@ class CortexTest(s_t_utils.SynTest):
1017
1017
  self.eq(('1', '2'), retn)
1018
1018
 
1019
1019
  with self.raises(s_exc.StormRuntimeError):
1020
- q = '$foo=$lib.list() $bar=$foo.index(10) return ( $bar )'
1020
+ q = '$foo=() $bar=$foo.index(10) return ( $bar )'
1021
1021
  await proxy.callStorm(q)
1022
1022
 
1023
1023
  with self.raises(s_exc.SynErr) as cm:
@@ -1033,6 +1033,26 @@ class CortexTest(s_t_utils.SynTest):
1033
1033
  self.eq(cm.exception.get('hehe'), 'haha')
1034
1034
  self.eq(cm.exception.get('key'), 1)
1035
1035
 
1036
+ # We convert StormLoopCtrl and StormGenrCtrl into StormRuntimeError
1037
+ opts = {'vars': {'i': 2}}
1038
+ q = 'if ($i = 2) { break }'
1039
+ with self.raises(s_exc.StormRuntimeError) as cm:
1040
+ await core.callStorm(q, opts=opts)
1041
+ self.eq(cm.exception.get('mesg'),
1042
+ 'Loop control statement "break" used outside of a loop.')
1043
+
1044
+ q = 'if ($i = 2) { continue }'
1045
+ with self.raises(s_exc.StormRuntimeError) as cm:
1046
+ await core.callStorm(q, opts=opts)
1047
+ self.eq(cm.exception.get('mesg'),
1048
+ 'Loop control statement "continue" used outside of a loop.')
1049
+
1050
+ q = 'if ($i = 2) { stop }'
1051
+ with self.raises(s_exc.StormRuntimeError) as cm:
1052
+ await core.callStorm(q, opts=opts)
1053
+ self.eq(cm.exception.get('mesg'),
1054
+ 'Generator control statement "stop" used outside of a generator function.')
1055
+
1036
1056
  with self.getAsyncLoggerStream('synapse.lib.view', 'callStorm cancelled') as stream:
1037
1057
  async with core.getLocalProxy() as proxy:
1038
1058
 
@@ -1069,7 +1089,7 @@ class CortexTest(s_t_utils.SynTest):
1069
1089
  self.eq('ok', retn.get('status'))
1070
1090
  self.eq('asdf', retn['result'])
1071
1091
 
1072
- body = {'query': '$foo=$lib.list() $bar=$foo.index(10) return ( $bar )'}
1092
+ body = {'query': '$foo=() $bar=$foo.index(10) return ( $bar )'}
1073
1093
  async with sess.get(f'https://localhost:{port}/api/v1/storm/call', json=body) as resp:
1074
1094
  retn = await resp.json()
1075
1095
  self.eq('err', retn.get('status'))
@@ -1081,7 +1101,7 @@ class CortexTest(s_t_utils.SynTest):
1081
1101
  retn = await resp.json()
1082
1102
  self.eq('err', retn.get('status'))
1083
1103
  self.eq('StormExit', retn.get('code'))
1084
- self.eq('', retn.get('mesg'))
1104
+ self.eq('StormExit: ', retn.get('mesg'))
1085
1105
 
1086
1106
  # No body
1087
1107
  async with sess.get(f'https://localhost:{port}/api/v1/storm/call') as resp:
@@ -1760,7 +1780,7 @@ class CortexTest(s_t_utils.SynTest):
1760
1780
  self.len(1, nodes)
1761
1781
  self.eq(set(nodes[0].tags.keys()), {'foo', 'bar', 'bar.baz'})
1762
1782
 
1763
- nodes = await wcore.nodes('$foo=$lib.list("foo", "bar.baz") [test:int=4 +#$foo]')
1783
+ nodes = await wcore.nodes('$foo=(["foo", "bar.baz"]) [test:int=4 +#$foo]')
1764
1784
  self.len(1, nodes)
1765
1785
  self.eq(set(nodes[0].tags.keys()), {'foo', 'bar', 'bar.baz'})
1766
1786
 
@@ -3499,6 +3519,97 @@ class CortexBasicTest(s_t_utils.SynTest):
3499
3519
  for node in nodes:
3500
3520
  self.nn(node.getTag('hehe'))
3501
3521
 
3522
+ # Break and Continue cannot cross function boundaries and will instead raise a catchable StormRuntimeError
3523
+ keywords = ('break', 'continue')
3524
+ base_func_q = '''
3525
+ function inner(v) {
3526
+ if ( $v = 2 ) {
3527
+ KEYWORD
3528
+ }
3529
+ return ( $v )
3530
+ }
3531
+ $N = (5)
3532
+
3533
+ for $valu in $lib.range($N) {
3534
+ $lib.print(`{$inner($valu)}/{$N}`)
3535
+ }
3536
+ '''
3537
+ func_catch_q = '''
3538
+ function inner(v) {
3539
+ if ( $v = 2 ) {
3540
+ KEYWORD
3541
+ }
3542
+ return ( $v )
3543
+ }
3544
+ $N = (5)
3545
+ try {
3546
+ for $valu in $lib.range($N) {
3547
+ $lib.print(`{$inner($valu)}/{$N}`)
3548
+ }
3549
+ } catch StormRuntimeError as err {
3550
+ $lib.print(`caught: {$err.mesg}`)
3551
+ }
3552
+ '''
3553
+ for keyword in keywords:
3554
+ q = base_func_q.replace('KEYWORD', keyword)
3555
+ msgs = await core.stormlist(q)
3556
+ self.stormIsInPrint('1/5', msgs)
3557
+ self.stormNotInPrint('2/5', msgs)
3558
+ self.stormIsInErr(f'function inner - Loop control statement "{keyword}" used outside of a loop.',
3559
+ msgs)
3560
+
3561
+ q = func_catch_q.replace('KEYWORD', keyword)
3562
+ msgs = await core.stormlist(q)
3563
+ self.stormIsInPrint('1/5', msgs)
3564
+ self.stormNotInPrint('2/5', msgs)
3565
+ self.stormIsInPrint(f'function inner - Loop control statement "{keyword}" used outside of a loop.',
3566
+ msgs)
3567
+
3568
+ # The toplevel use of the keywords will convert them into StormRuntimeError in the message stream
3569
+ # but prevent them from being caught.
3570
+ base_top_q = '''
3571
+ $N = (5)
3572
+ for $j in $lib.range($N) {
3573
+ if ($j = 2) { break }
3574
+ $lib.print(`{$j}/{$N}`)
3575
+ }
3576
+ if ($j = 2) {
3577
+ KEYWORD
3578
+ }
3579
+ '''
3580
+ top_catch_q = '''
3581
+ $N = (5)
3582
+ for $j in $lib.range($N) {
3583
+ if ($j = 2) { break }
3584
+ $lib.print(`{$j}/{$N}`)
3585
+ }
3586
+ try {
3587
+ if ($j = 2) {
3588
+ KEYWORD
3589
+ }
3590
+ } catch StormRuntimeError as err {
3591
+ $lib.print(`caught: {$err.mesg}`)
3592
+ }
3593
+ '''
3594
+ for keyword in keywords:
3595
+ q = base_top_q.replace('KEYWORD', keyword)
3596
+ msgs = await core.stormlist(q)
3597
+ self.stormIsInPrint('1/5', msgs)
3598
+ self.stormNotInPrint('2/5', msgs)
3599
+ self.stormIsInErr(f'Loop control statement "{keyword}" used outside of a loop.',
3600
+ msgs)
3601
+ errname = [m[1][0] for m in msgs if m[0] == 'err'][0]
3602
+ self.eq(errname, 'StormRuntimeError')
3603
+
3604
+ q = top_catch_q.replace('KEYWORD', keyword)
3605
+ msgs = await core.stormlist(q)
3606
+ self.stormIsInPrint('1/5', msgs)
3607
+ self.stormNotInPrint('2/5', msgs)
3608
+ self.stormIsInErr(f'Loop control statement "{keyword}" used outside of a loop.',
3609
+ msgs)
3610
+ errname = [m[1][0] for m in msgs if m[0] == 'err'][0]
3611
+ self.eq(errname, 'StormRuntimeError')
3612
+
3502
3613
  async def test_storm_varcall(self):
3503
3614
 
3504
3615
  async with self.getTestCore() as core:
@@ -5119,6 +5230,14 @@ class CortexBasicTest(s_t_utils.SynTest):
5119
5230
  self.eq(('inet:fqdn', 'nest.com'), nodes[0].ndef)
5120
5231
  self.eq(('inet:fqdn', 'nest.com'), nodes[1].ndef)
5121
5232
 
5233
+ with self.raises(s_exc.StormRuntimeError) as err:
5234
+ await core.nodes('[ it:dev:int=1 ] for $n in $node.value() { }')
5235
+ self.isin("'int' object is not iterable: 1", err.exception.errinfo.get('mesg'))
5236
+
5237
+ with self.raises(s_exc.StormRuntimeError) as err:
5238
+ await core.nodes('for $n in { .created return($node) } { }')
5239
+ self.isin("'node' object is not iterable", err.exception.errinfo.get('mesg'))
5240
+
5122
5241
  async def test_storm_whileloop(self):
5123
5242
 
5124
5243
  async with self.getTestCore() as core:
@@ -5460,7 +5579,7 @@ class CortexBasicTest(s_t_utils.SynTest):
5460
5579
  self.len(1, nodes)
5461
5580
 
5462
5581
  async def test_storm_order(self):
5463
- q = '''[test:str=foo :hehe=bar] $tvar=$lib.text() $tvar.add(1) $tvar.add(:hehe) $lib.print($tvar.str()) '''
5582
+ q = '''[test:str=foo :hehe=bar] $tvar=() $tvar.append(1) $tvar.append(:hehe) $lib.print($lib.str.join('', $tvar)) '''
5464
5583
  async with self.getTestCore() as core:
5465
5584
  mesgs = await core.stormlist(q)
5466
5585
  self.stormIsInPrint('1bar', mesgs)
@@ -5684,7 +5803,7 @@ class CortexBasicTest(s_t_utils.SynTest):
5684
5803
 
5685
5804
  url02 = core02.getLocalUrl()
5686
5805
  opts = {'vars': {'url01': url01, 'url02': url02}}
5687
- strim = 'return($lib.cell.trimNexsLog(consumers=$lib.list($url01, $url02), timeout=$lib.null))'
5806
+ strim = 'return($lib.cell.trimNexsLog(consumers=($url01, $url02), timeout=$lib.null))'
5688
5807
 
5689
5808
  await core00.nodes('[ inet:ipv4=11.0.0.0/28 ]')
5690
5809
  ips00 = await core00.count('inet:ipv4')
synapse/tests/test_exc.py CHANGED
@@ -16,6 +16,7 @@ class ExcTest(s_t_utils.SynTest):
16
16
  def test_basic(self):
17
17
  e = s_exc.SynErr(mesg='words', foo='bar')
18
18
  self.eq(e.get('foo'), 'bar')
19
+ self.eq(e.items(), {'mesg': 'words', 'foo': 'bar'})
19
20
  self.eq("SynErr: foo='bar' mesg='words'", str(e))
20
21
  e.set('hehe', 1234)
21
22
  e.set('foo', 'words')
@@ -441,7 +441,7 @@ class AgendaTest(s_t_utils.SynTest):
441
441
  await self.asyncraises(s_exc.DupIden, core.addCronJob(cdef))
442
442
  await core.delCronJob(viewiden)
443
443
 
444
- self.nn(core.getAuthGate(viewiden))
444
+ self.nn(await core.getAuthGate(viewiden))
445
445
 
446
446
  async def test_agenda_persistence(self):
447
447
  ''' Test we can make/change/delete appointments and they are persisted to storage '''
@@ -1097,3 +1097,127 @@ class AgendaTest(s_t_utils.SynTest):
1097
1097
  self.eq(cdef01.get('lastresult'), 'cancelled')
1098
1098
  self.gt(cdef00['laststarttime'], 0)
1099
1099
  self.eq(cdef00['laststarttime'], cdef01['laststarttime'])
1100
+
1101
+ async def test_agenda_graceful_promotion_with_running_cron(self):
1102
+
1103
+ async with self.getTestAha() as aha:
1104
+
1105
+ conf00 = {
1106
+ 'aha:provision': await aha.addAhaSvcProv('00.cortex')
1107
+ }
1108
+
1109
+ async with self.getTestCore(conf=conf00) as core00:
1110
+ self.false(core00.conf.get('mirror'))
1111
+
1112
+ q = '''
1113
+ while((true)) {
1114
+ $lib.log.error('I AM A ERROR LOG MESSAGE')
1115
+ $lib.time.sleep(6)
1116
+ }
1117
+ '''
1118
+ msgs = await core00.stormlist('cron.at --now $q', opts={'vars': {'q': q}})
1119
+ self.stormHasNoWarnErr(msgs)
1120
+
1121
+ crons00 = await core00.callStorm('return($lib.cron.list())')
1122
+ self.len(1, crons00)
1123
+
1124
+ prov01 = {'mirror': '00.cortex'}
1125
+ conf01 = {
1126
+ 'aha:provision': await aha.addAhaSvcProv('01.cortex', provinfo=prov01),
1127
+ }
1128
+
1129
+ async with self.getTestCore(conf=conf01) as core01:
1130
+
1131
+ with self.getAsyncLoggerStream('synapse.storm.log', 'I AM A ERROR LOG MESSAGE') as stream:
1132
+ self.true(await stream.wait(timeout=6))
1133
+
1134
+ cron = await core00.callStorm('return($lib.cron.list())')
1135
+ self.len(1, cron)
1136
+ self.true(cron[0].get('isrunning'))
1137
+
1138
+ await core01.promote(graceful=True)
1139
+
1140
+ self.false(core00.isactive)
1141
+ self.true(core01.isactive)
1142
+
1143
+ await core00.sync()
1144
+
1145
+ cron00 = await core00.callStorm('return($lib.cron.list())')
1146
+ self.len(1, cron00)
1147
+ self.false(cron00[0].get('isrunning'))
1148
+ self.eq(cron00[0].get('lasterrs')[0], 'aborted')
1149
+
1150
+ cron01 = await core01.callStorm('return($lib.cron.list())')
1151
+ self.len(1, cron01)
1152
+ self.false(cron01[0].get('isrunning'))
1153
+ self.eq(cron01[0].get('lasterrs')[0], 'aborted')
1154
+
1155
+ async def test_agenda_force_promotion_with_running_cron(self):
1156
+
1157
+ async with self.getTestAha() as aha:
1158
+
1159
+ conf00 = {
1160
+ 'aha:provision': await aha.addAhaSvcProv('00.cortex')
1161
+ }
1162
+
1163
+ async with self.getTestCore(conf=conf00) as core00:
1164
+ self.false(core00.conf.get('mirror'))
1165
+
1166
+ q = '''
1167
+ while((true)) {
1168
+ $lib.log.error('I AM A ERROR LOG MESSAGE')
1169
+ $lib.time.sleep(6)
1170
+ }
1171
+ '''
1172
+ msgs = await core00.stormlist('cron.at --now $q', opts={'vars': {'q': q}})
1173
+ self.stormHasNoWarnErr(msgs)
1174
+
1175
+ crons00 = await core00.callStorm('return($lib.cron.list())')
1176
+ self.len(1, crons00)
1177
+
1178
+ prov01 = {'mirror': '00.cortex'}
1179
+ conf01 = {
1180
+ 'aha:provision': await aha.addAhaSvcProv('01.cortex', provinfo=prov01),
1181
+ }
1182
+
1183
+ async with self.getTestCore(conf=conf01) as core01:
1184
+
1185
+ cron = await core00.callStorm('return($lib.cron.list())')
1186
+ self.len(1, cron)
1187
+ self.true(cron[0].get('isrunning'))
1188
+
1189
+ await core01.promote(graceful=False)
1190
+
1191
+ self.true(core00.isactive)
1192
+ self.true(core01.isactive)
1193
+
1194
+ cron01 = await core01.callStorm('return($lib.cron.list())')
1195
+ self.len(1, cron01)
1196
+ self.false(cron01[0].get('isrunning'))
1197
+ self.eq(cron01[0].get('lasterrs')[0], 'aborted')
1198
+
1199
+ async def test_agenda_clear_running_none_nexttime(self):
1200
+
1201
+ async with self.getTestCore() as core:
1202
+
1203
+ cdef = {
1204
+ 'creator': core.auth.rootuser.iden,
1205
+ 'iden': s_common.guid(),
1206
+ 'storm': '$lib.log.info("test")',
1207
+ 'reqs': {},
1208
+ 'incunit': 'minute',
1209
+ 'incvals': 1
1210
+ }
1211
+ await core.addCronJob(cdef)
1212
+
1213
+ appt = core.agenda.appts[cdef['iden']]
1214
+ self.true(appt in core.agenda.apptheap)
1215
+
1216
+ appt.isrunning = True
1217
+ appt.nexttime = None
1218
+
1219
+ await core.agenda.clearRunningStatus()
1220
+ self.false(appt in core.agenda.apptheap)
1221
+
1222
+ crons = await core.callStorm('return($lib.cron.list())')
1223
+ self.len(1, crons)
@@ -59,7 +59,7 @@ class AhaTest(s_test.SynTest):
59
59
  self.len(ahacount, await proxy0.getAhaUrls())
60
60
  self.len(ahacount, await proxy0.getAhaServers())
61
61
 
62
- purl = await proxy0.addAhaClone(zoinks)
62
+ purl = await proxy0.addAhaClone(zoinks, port=0)
63
63
 
64
64
  conf1 = {'clone': purl}
65
65
  async with self.getTestAha(conf=conf1, dirn=dir1) as aha1:
@@ -574,7 +574,7 @@ class AhaTest(s_test.SynTest):
574
574
  }
575
575
  s_common.yamlsave(axonconf, axonpath, 'cell.yaml')
576
576
 
577
- argv = (axonpath, '--auth-passwd', 'rootbeer')
577
+ argv = (axonpath, '--auth-passwd', 'rootbeer', '--https', '0')
578
578
  async with await s_axon.Axon.initFromArgv(argv) as axon:
579
579
 
580
580
  # opts were copied through successfully
@@ -1161,7 +1161,8 @@ class AhaTest(s_test.SynTest):
1161
1161
  aconf = {
1162
1162
  'aha:name': 'aha',
1163
1163
  'aha:network': networkname,
1164
- 'provision:listen': f'ssl://aha.{networkname}:0'
1164
+ 'dmon:listen': f'ssl://aha.{networkname}:0',
1165
+ 'provision:listen': f'ssl://aha.{networkname}:0',
1165
1166
  }
1166
1167
  name = aconf.get('aha:name')
1167
1168
  netw = aconf.get('aha:network')
@@ -1300,11 +1301,17 @@ class AhaTest(s_test.SynTest):
1300
1301
  conf = {
1301
1302
  'aha:network': 'synapse',
1302
1303
  'dns:name': 'here.loop.vertex.link',
1304
+ 'dmon:listen': 'ssl://0.0.0.0:0?hostname=here.loop.vertex.link&ca=synapse',
1303
1305
  }
1304
- mesg = 'provision listening: ssl://0.0.0.0:27272?hostname=here.loop.vertex.link'
1305
- with self.getAsyncLoggerStream('synapse.lib.aha', mesg) as stream:
1306
+
1307
+ orig = s_aha.AhaCell._getProvListen
1308
+ def _getProvListen(_self):
1309
+ ret = orig(_self)
1310
+ self.eq(ret, 'ssl://0.0.0.0:27272?hostname=here.loop.vertex.link')
1311
+ return 'ssl://0.0.0.0:0?hostname=here.loop.vertex.link'
1312
+
1313
+ with mock.patch('synapse.lib.aha.AhaCell._getProvListen', _getProvListen):
1306
1314
  async with self.getTestCell(s_aha.AhaCell, conf=conf) as aha:
1307
- self.true(await stream.wait(timeout=6))
1308
1315
  # And the URL works with our listener :)
1309
1316
  provurl = await aha.addAhaUserEnroll('bob.grey')
1310
1317
  async with await s_telepath.openurl(provurl) as prox: