synapse 2.205.0__py311-none-any.whl → 2.207.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 (38) hide show
  1. synapse/axon.py +8 -8
  2. synapse/cortex.py +14 -1
  3. synapse/lib/aha.py +13 -8
  4. synapse/lib/httpapi.py +196 -97
  5. synapse/lib/lmdbslab.py +2 -0
  6. synapse/lib/modelrev.py +3 -3
  7. synapse/lib/schemas.py +11 -0
  8. synapse/lib/spooled.py +2 -1
  9. synapse/lib/stormhttp.py +6 -6
  10. synapse/lib/stormlib/aha.py +5 -1
  11. synapse/lib/stormlib/model.py +1 -1
  12. synapse/lib/stormtypes.py +53 -17
  13. synapse/lib/version.py +2 -2
  14. synapse/models/base.py +9 -0
  15. synapse/models/inet.py +9 -1
  16. synapse/models/infotech.py +5 -0
  17. synapse/models/telco.py +10 -0
  18. synapse/tests/test_axon.py +52 -41
  19. synapse/tests/test_cortex.py +18 -6
  20. synapse/tests/test_lib_aha.py +17 -0
  21. synapse/tests/test_lib_cell.py +5 -3
  22. synapse/tests/test_lib_httpapi.py +225 -33
  23. synapse/tests/test_lib_lmdbslab.py +30 -0
  24. synapse/tests/test_lib_modelrev.py +7 -7
  25. synapse/tests/test_lib_spooled.py +2 -0
  26. synapse/tests/test_lib_stormhttp.py +13 -0
  27. synapse/tests/test_lib_stormlib_aha.py +7 -7
  28. synapse/tests/test_lib_stormlib_cortex.py +61 -60
  29. synapse/tests/test_lib_stormtypes.py +8 -0
  30. synapse/tests/test_model_infotech.py +2 -0
  31. synapse/tests/test_model_telco.py +4 -1
  32. synapse/tools/aha/easycert.py +4 -0
  33. synapse/tools/aha/mirror.py +6 -4
  34. {synapse-2.205.0.dist-info → synapse-2.207.0.dist-info}/METADATA +1 -1
  35. {synapse-2.205.0.dist-info → synapse-2.207.0.dist-info}/RECORD +38 -38
  36. {synapse-2.205.0.dist-info → synapse-2.207.0.dist-info}/WHEEL +0 -0
  37. {synapse-2.205.0.dist-info → synapse-2.207.0.dist-info}/licenses/LICENSE +0 -0
  38. {synapse-2.205.0.dist-info → synapse-2.207.0.dist-info}/top_level.txt +0 -0
synapse/lib/modelrev.py CHANGED
@@ -1455,7 +1455,7 @@ class ModelMigration_0_2_31:
1455
1455
 
1456
1456
  # Pick up and classify all bad CPE nodes
1457
1457
  for idx, layer in enumerate(self.layers):
1458
- logger.debug(f'Classifying nodes in layer {idx}')
1458
+ logger.debug('Classifying nodes in layer %s %s', idx, layer.iden)
1459
1459
 
1460
1460
  async for buid, sode in layer.getStorNodesByForm('it:sec:cpe'):
1461
1461
 
@@ -1499,7 +1499,7 @@ class ModelMigration_0_2_31:
1499
1499
 
1500
1500
  # Pick up all related CPE node info. The majority of the work happens in this loop
1501
1501
  for idx, layer in enumerate(self.layers):
1502
- logger.debug(f'Processing nodes in layer {idx}')
1502
+ logger.debug('Processing nodes in layer %s %s', idx, layer.iden)
1503
1503
 
1504
1504
  for buid, node in self.nodes.items():
1505
1505
  await self._loadNode(layer, buid, node=node)
@@ -1541,7 +1541,7 @@ class ModelMigration_0_2_31:
1541
1541
  await self.todos.clear()
1542
1542
 
1543
1543
  for idx, layer in enumerate(self.layers):
1544
- logger.debug(f'Processing references in layer {idx}')
1544
+ logger.debug('Processing references in layer %s %s', idx, layer.iden)
1545
1545
 
1546
1546
  async for entry in todotmp:
1547
1547
  match entry:
synapse/lib/schemas.py CHANGED
@@ -1128,3 +1128,14 @@ _reqValidOauth2TokenResponseSchema = {
1128
1128
  'required': ['access_token', 'expires_in'],
1129
1129
  }
1130
1130
  reqValidOauth2TokenResponse = s_config.getJsValidator(_reqValidOauth2TokenResponseSchema)
1131
+
1132
+ _httpLoginV1Schema = {
1133
+ 'type': 'object',
1134
+ 'properties': {
1135
+ 'user': {'type': 'string'},
1136
+ 'passwd': {'type': 'string'},
1137
+ },
1138
+ 'additionalProperties': False,
1139
+ 'required': ['user', 'passwd'],
1140
+ }
1141
+ reqValidHttpLoginV1 = s_config.getJsValidator(_httpLoginV1Schema)
synapse/lib/spooled.py CHANGED
@@ -8,6 +8,7 @@ import synapse.lib.msgpack as s_msgpack
8
8
  import synapse.lib.lmdbslab as s_lmdbslab
9
9
 
10
10
  MAX_SPOOL_SIZE = 10000
11
+ DEFAULT_MAPSIZE = s_const.mebibyte * 32
11
12
 
12
13
  class Spooled(s_base.Base):
13
14
  '''
@@ -48,7 +49,7 @@ class Spooled(s_base.Base):
48
49
 
49
50
  slabpath = tempfile.mkdtemp(dir=dirn, prefix='spooled_', suffix='.lmdb')
50
51
 
51
- self.slab = await s_lmdbslab.Slab.anit(slabpath, map_size=s_const.mebibyte * 32)
52
+ self.slab = await s_lmdbslab.Slab.anit(slabpath, map_size=DEFAULT_MAPSIZE)
52
53
  if self.cell is not None:
53
54
  self.slab.addResizeCallback(self.cell.checkFreeSpace)
54
55
 
synapse/lib/stormhttp.py CHANGED
@@ -457,23 +457,23 @@ class LibHttp(s_stormtypes.Lib):
457
457
  hnfo = {
458
458
  'code': hist.status,
459
459
  'reason': await self.codereason(hist.status),
460
- 'headers': dict(hist.headers),
460
+ 'headers': {str(k): v for k, v in hist.headers.items()},
461
461
  'url': str(hist.url),
462
462
  # aiohttp has already closed the connection by this point
463
463
  # so there is no connection to read a body from.
464
464
  'body': b'',
465
465
  'history': [],
466
- 'request_headers': dict(hist.request_info.headers)
466
+ 'request_headers': {str(k): v for k, v in hist.request_info.headers.items()}
467
467
  }
468
468
  history.append(hnfo)
469
469
  info = {
470
470
  'code': resp.status,
471
471
  'reason': await self.codereason(resp.status),
472
- 'headers': dict(resp.headers),
472
+ 'headers': {str(k): v for k, v in resp.headers.items()},
473
473
  'url': str(resp.url),
474
474
  'body': await resp.read(),
475
475
  'history': history,
476
- 'request_headers': dict(resp.request_info.headers)
476
+ 'request_headers': {str(k): v for k, v in resp.request_info.headers.items()},
477
477
  }
478
478
  return HttpResp(info)
479
479
 
@@ -492,11 +492,11 @@ class LibHttp(s_stormtypes.Lib):
492
492
  'err': err,
493
493
  'code': -1,
494
494
  'reason': reason,
495
- 'headers': dict(),
495
+ 'headers': {},
496
496
  'url': url,
497
497
  'body': b'',
498
498
  'history': [],
499
- 'request_headers': dict(),
499
+ 'request_headers': {},
500
500
  }
501
501
  return HttpResp(info)
502
502
 
@@ -691,6 +691,7 @@ The ready column indicates that a service has entered into the realtime change w
691
691
  {"name": "host", "width": 16},
692
692
  {"name": "port", "width": 8},
693
693
  {"name": "version", "width": 12},
694
+ {"name": "synapse", "width": 12},
694
695
  {"name": "nexus idx", "width": 10},
695
696
  ],
696
697
  "separators": {
@@ -732,6 +733,7 @@ The ready column indicates that a service has entered into the realtime change w
732
733
  'host': $svcinfo.urlinfo.host,
733
734
  'port': $svcinfo.urlinfo.port,
734
735
  'version': '<unknown>',
736
+ 'synapse_version': '<unknown>',
735
737
  'nexs_indx': (0)
736
738
  })
737
739
  if ($cell_infos.$svcname) {
@@ -743,7 +745,8 @@ The ready column indicates that a service has entered into the realtime change w
743
745
  } else {
744
746
  $status.role = 'leader'
745
747
  }
746
- $status.version = $info.synapse.verstring
748
+ $status.version = $info.cell.verstring
749
+ $status.synapse_version = $info.synapse.verstring
747
750
  }
748
751
  $group_status.append($status)
749
752
  }
@@ -779,6 +782,7 @@ The ready column indicates that a service has entered into the realtime change w
779
782
  $status.host,
780
783
  $status.port,
781
784
  $status.version,
785
+ $status.synapse_version,
782
786
  $status.nexs_indx
783
787
  )
784
788
  $lib.print($printer.row($row))
@@ -1181,7 +1181,7 @@ class LibModelMigrations_0_2_31(s_stormtypes.Lib):
1181
1181
  await self.runt.printf(f' layer: {layriden}')
1182
1182
  for iden, refinfo in reflist:
1183
1183
  form, prop, *_ = refinfo
1184
- await self.runt.printf(f' - {form}:{prop} (iden: {iden}')
1184
+ await self.runt.printf(f' - {form}:{prop} (iden: {iden})')
1185
1185
 
1186
1186
  n1edges = node['n1edges']
1187
1187
  n2edges = node['n2edges']
synapse/lib/stormtypes.py CHANGED
@@ -1235,7 +1235,7 @@ class LibBase(Lib):
1235
1235
  Examples:
1236
1236
  Fire an event called ``demo`` with some data::
1237
1237
 
1238
- cli> storm $foo='bar' $lib.fire('demo', foo=$foo, knight='ni')
1238
+ storm> $foo='bar' $lib.fire('demo', foo=$foo, knight='ni')
1239
1239
  ...
1240
1240
  ('storm:fire', {'type': 'demo', 'data': {'foo': 'bar', 'knight': 'ni'}})
1241
1241
  ...
@@ -1268,7 +1268,7 @@ class LibBase(Lib):
1268
1268
  Examples:
1269
1269
  Create a dictionary object with a key whose value is null, and call ``$lib.fire()`` with it::
1270
1270
 
1271
- cli> storm $d=({"key": $lib.null}) $lib.fire('demo', d=$d)
1271
+ storm> $d=({"key": $lib.null}) $lib.fire('demo', d=$d)
1272
1272
  ('storm:fire', {'type': 'demo', 'data': {'d': {'key': None}}})
1273
1273
  ''',
1274
1274
  'type': 'null', },
@@ -1295,7 +1295,7 @@ class LibBase(Lib):
1295
1295
  Examples:
1296
1296
  Conditionally print a statement based on the constant value::
1297
1297
 
1298
- cli> storm if $lib.true { $lib.print('Is True') } else { $lib.print('Is False') }
1298
+ storm> if $lib.true { $lib.print('Is True') } else { $lib.print('Is False') }
1299
1299
  Is True
1300
1300
  ''',
1301
1301
  'type': 'boolean', },
@@ -1305,7 +1305,7 @@ class LibBase(Lib):
1305
1305
  Examples:
1306
1306
  Conditionally print a statement based on the constant value::
1307
1307
 
1308
- cli> storm if $lib.false { $lib.print('Is True') } else { $lib.print('Is False') }
1308
+ storm> if $lib.false { $lib.print('Is True') } else { $lib.print('Is False') }
1309
1309
  Is False''',
1310
1310
  'type': 'boolean', },
1311
1311
  {'name': 'text', 'desc': 'Get a Storm Text object. This is deprecated; please use a list to append strings to, and then use ``$lib.str.join()`` to join them on demand.',
@@ -1344,19 +1344,19 @@ class LibBase(Lib):
1344
1344
  Examples:
1345
1345
  Print a simple string::
1346
1346
 
1347
- cli> storm $lib.print("Hello world!")
1347
+ storm> $lib.print("Hello world!")
1348
1348
  Hello world!
1349
1349
 
1350
1350
  Format and print string based on variables::
1351
1351
 
1352
- cli> storm $d=({"key1": (1), "key2": "two"})
1352
+ storm> $d=({"key1": (1), "key2": "two"})
1353
1353
  for ($key, $value) in $d { $lib.print('{k} => {v}', k=$key, v=$value) }
1354
1354
  key1 => 1
1355
1355
  key2 => two
1356
1356
 
1357
1357
  Use values off of a node to format and print string::
1358
1358
 
1359
- cli> storm inet:ipv4:asn
1359
+ storm> inet:ipv4:asn
1360
1360
  $lib.print("node: {ndef}, asn: {asn}", ndef=$node.ndef(), asn=:asn) | spin
1361
1361
  node: ('inet:ipv4', 16909060), asn: 1138
1362
1362
 
@@ -1376,7 +1376,7 @@ class LibBase(Lib):
1376
1376
  Examples:
1377
1377
  Generate a sequence of integers based on the size of an array::
1378
1378
 
1379
- cli> storm $a=(foo,bar,(2)) for $i in $lib.range($lib.len($a)) {$lib.fire('test', indx=$i, valu=$a.$i)}
1379
+ storm> $a=(foo,bar,(2)) for $i in $lib.range($lib.len($a)) {$lib.fire('test', indx=$i, valu=$a.$i)}
1380
1380
  Executing query at 2021/03/22 19:25:48.835
1381
1381
  ('storm:fire', {'type': 'test', 'data': {'index': 0, 'valu': 'foo'}})
1382
1382
  ('storm:fire', {'type': 'test', 'data': {'index': 1, 'valu': 'bar'}})
@@ -2029,7 +2029,7 @@ class LibStr(Lib):
2029
2029
  Examples:
2030
2030
  Join together a list of strings with a dot separator::
2031
2031
 
2032
- cli> storm $foo=$lib.str.join('.', ('rep', 'vtx', 'tag')) $lib.print($foo)
2032
+ storm> $foo=$lib.str.join('.', ('rep', 'vtx', 'tag')) $lib.print($foo)
2033
2033
 
2034
2034
  rep.vtx.tag''',
2035
2035
  'type': {'type': 'function', '_funcname': 'join',
@@ -2050,7 +2050,7 @@ class LibStr(Lib):
2050
2050
  Examples:
2051
2051
  Format a string with a fixed argument and a variable::
2052
2052
 
2053
- cli> storm $list=(1,2,3,4)
2053
+ storm> $list=(1,2,3,4)
2054
2054
  $str=$lib.str.format('Hello {name}, your list is {list}!', name='Reader', list=$list)
2055
2055
  $lib.print($str)
2056
2056
 
@@ -2324,7 +2324,7 @@ class LibAxon(Lib):
2324
2324
  Examples:
2325
2325
  Save a base64 encoded buffer to the Axon::
2326
2326
 
2327
- cli> storm $s='dGVzdA==' $buf=$lib.base64.decode($s) ($size, $sha256)=$lib.axon.put($buf)
2327
+ storm> $s='dGVzdA==' $buf=$lib.base64.decode($s) ($size, $sha256)=$lib.axon.put($buf)
2328
2328
  $lib.print('size={size} sha256={sha256}', size=$size, sha256=$sha256)
2329
2329
 
2330
2330
  size=4 sha256=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08''',
@@ -2340,7 +2340,7 @@ class LibAxon(Lib):
2340
2340
  Check if the Axon has a given file::
2341
2341
 
2342
2342
  # This example assumes the Axon does have the bytes
2343
- cli> storm if $lib.axon.has(9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08) {
2343
+ storm> if $lib.axon.has(9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08) {
2344
2344
  $lib.print("Has bytes")
2345
2345
  } else {
2346
2346
  $lib.print("Does not have bytes")
@@ -2812,7 +2812,7 @@ class LibBytes(Lib):
2812
2812
  Examples:
2813
2813
  Save a base64 encoded buffer to the Axon::
2814
2814
 
2815
- cli> storm $s='dGVzdA==' $buf=$lib.base64.decode($s) ($size, $sha256)=$lib.bytes.put($buf)
2815
+ storm> $s='dGVzdA==' $buf=$lib.base64.decode($s) ($size, $sha256)=$lib.bytes.put($buf)
2816
2816
  $lib.print('size={size} sha256={sha256}', size=$size, sha256=$sha256)
2817
2817
 
2818
2818
  size=4 sha256=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08''',
@@ -2828,7 +2828,7 @@ class LibBytes(Lib):
2828
2828
  Check if the Axon has a given file::
2829
2829
 
2830
2830
  # This example assumes the Axon does have the bytes
2831
- cli> storm if $lib.bytes.has(9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08) {
2831
+ storm> if $lib.bytes.has(9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08) {
2832
2832
  $lib.print("Has bytes")
2833
2833
  } else {
2834
2834
  $lib.print("Does not have bytes")
@@ -3002,7 +3002,7 @@ class LibTime(Lib):
3002
3002
  Examples:
3003
3003
  Convert a timestamp from seconds to millis and format it::
3004
3004
 
3005
- cli> storm $seconds=1594684800 $millis=$lib.time.fromunix($seconds)
3005
+ storm> $seconds=1594684800 $millis=$lib.time.fromunix($seconds)
3006
3006
  $str=$lib.time.format($millis, '%A %d, %B %Y') $lib.print($str)
3007
3007
 
3008
3008
  Tuesday 14, July 2020''',
@@ -3017,7 +3017,7 @@ class LibTime(Lib):
3017
3017
  Examples:
3018
3018
  Parse a string as for its month/day/year value into a timestamp::
3019
3019
 
3020
- cli> storm $s='06/01/2020' $ts=$lib.time.parse($s, '%m/%d/%Y') $lib.print($ts)
3020
+ storm> $s='06/01/2020' $ts=$lib.time.parse($s, '%m/%d/%Y') $lib.print($ts)
3021
3021
 
3022
3022
  1590969600000''',
3023
3023
  'type': {'type': 'function', '_funcname': '_parse',
@@ -3034,7 +3034,7 @@ class LibTime(Lib):
3034
3034
  Examples:
3035
3035
  Format a timestamp into a string::
3036
3036
 
3037
- cli> storm $now=$lib.time.now() $str=$lib.time.format($now, '%A %d, %B %Y') $lib.print($str)
3037
+ storm> $now=$lib.time.now() $str=$lib.time.format($now, '%A %d, %B %Y') $lib.print($str)
3038
3038
 
3039
3039
  Tuesday 14, July 2020''',
3040
3040
  'type': {'type': 'function', '_funcname': '_format',
@@ -3933,6 +3933,16 @@ class LibQueue(Lib):
3933
3933
  'returns': {'type': 'list',
3934
3934
  'desc': 'A list of queue definitions the current user is allowed to interact with.', }}},
3935
3935
  )
3936
+ _storm_lib_perms = (
3937
+ {'perm': ('queue', 'add'), 'gate': 'cortex',
3938
+ 'desc': 'Permits a user to create a named queue.'},
3939
+ {'perm': ('queue', 'get'), 'gate': 'queue',
3940
+ 'desc': 'Permits a user to access a queue. This allows the user to read from the queue and remove items from it.'},
3941
+ {'perm': ('queue', 'put'), 'gate': 'queue',
3942
+ 'desc': 'Permits a user to put items into a queue.'},
3943
+ {'perm': ('queue', 'del'), 'gate': 'queue',
3944
+ 'desc': 'Permits a user to delete a queue.'},
3945
+ )
3936
3946
  _storm_lib_path = ('queue',)
3937
3947
 
3938
3948
  def getObjLocals(self):
@@ -4649,6 +4659,26 @@ class Str(Prim):
4649
4659
  {'name': 'json', 'desc': 'Parse a JSON string and return the deserialized data.',
4650
4660
  'type': {'type': 'function', '_funcname': '_methStrJson', 'args': (),
4651
4661
  'returns': {'type': 'prim', 'desc': 'The JSON deserialized object.', }}},
4662
+ {'name': 'join', 'desc': '''
4663
+ Join items into a string using the current string as a separator.
4664
+
4665
+ Examples:
4666
+ Join together a list of strings with a dot separator::
4667
+
4668
+ storm> $sepr='.' $foo=$sepr.join(('rep', 'vtx', 'tag')) $lib.print($foo)
4669
+
4670
+ rep.vtx.tag
4671
+
4672
+ Join values inline together with a dot separator::
4673
+
4674
+ storm> $foo=('.').join(('rep', 'vtx', 'tag')) $lib.print($foo)
4675
+
4676
+ rep.vtx.tag''',
4677
+ 'type': {'type': 'function', '_funcname': '_methStrJoin',
4678
+ 'args': (
4679
+ {'name': 'items', 'type': 'list', 'desc': 'A list of items to join together.', },
4680
+ ),
4681
+ 'returns': {'type': 'str', 'desc': 'The joined string.', }}},
4652
4682
  )
4653
4683
  _storm_typename = 'str'
4654
4684
  _ismutable = False
@@ -4679,6 +4709,7 @@ class Str(Prim):
4679
4709
  'reverse': self._methStrReverse,
4680
4710
  'format': self._methStrFormat,
4681
4711
  'json': self._methStrJson,
4712
+ 'join': self._methStrJoin,
4682
4713
  }
4683
4714
 
4684
4715
  def __int__(self):
@@ -4798,6 +4829,11 @@ class Str(Prim):
4798
4829
  async def _methStrJson(self):
4799
4830
  return s_json.loads(self.valu)
4800
4831
 
4832
+ @stormfunc(readonly=True)
4833
+ async def _methStrJoin(self, items):
4834
+ strs = [await tostr(item) async for item in toiter(items)]
4835
+ return self.valu.join(strs)
4836
+
4801
4837
  @registry.registerType
4802
4838
  class Bytes(Prim):
4803
4839
  '''
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, 205, 0)
226
+ version = (2, 207, 0)
227
227
  verstring = '.'.join([str(x) for x in version])
228
- commit = 'd985f8b93669529b2d90895baabb1dc289e287df'
228
+ commit = 'b5307edb2fd8ba01d47f5f38bcd6033237deda7e'
synapse/models/base.py CHANGED
@@ -188,6 +188,15 @@ class BaseModule(s_module.CoreModule):
188
188
  (('meta:ruleset', 'has', 'meta:rule'), {
189
189
  'doc': 'The meta:ruleset includes the meta:rule.'}),
190
190
 
191
+ (('meta:ruleset', 'has', 'inet:service:rule'), {
192
+ 'doc': 'The meta:ruleset includes the inet:service:rule.'}),
193
+
194
+ (('meta:ruleset', 'has', 'it:app:snort:rule'), {
195
+ 'doc': 'The meta:ruleset includes the it:app:snort:rule.'}),
196
+
197
+ (('meta:ruleset', 'has', 'it:app:yara:rule'), {
198
+ 'doc': 'The meta:ruleset includes the it:app:yara:rule.'}),
199
+
191
200
  (('meta:rule', 'matches', None), {
192
201
  'doc': 'The meta:rule has matched on target node.'}),
193
202
 
synapse/models/inet.py CHANGED
@@ -108,12 +108,20 @@ class Addr(s_types.Str):
108
108
  s_types.Str.postTypeInit(self)
109
109
  self.setNormFunc(str, self._normPyStr)
110
110
 
111
+ self.defport = self.opts.get('defport', None)
112
+ self.defproto = self.opts.get('defproto', 'tcp')
113
+
111
114
  def _getPort(self, valu):
115
+
112
116
  parts = valu.split(':', 1)
113
117
  if len(parts) == 2:
114
118
  valu, port = parts
115
119
  port = self.modl.type('inet:port').norm(port)[0]
116
120
  return valu, port, f':{port}'
121
+
122
+ if self.defport:
123
+ return valu, self.defport, f':{self.defport}'
124
+
117
125
  return valu, None, ''
118
126
 
119
127
  def _normPyStr(self, valu):
@@ -123,7 +131,7 @@ class Addr(s_types.Str):
123
131
  # no protos use case sensitivity yet...
124
132
  valu = valu.lower()
125
133
 
126
- proto = 'tcp'
134
+ proto = self.defproto
127
135
  parts = valu.split('://', 1)
128
136
  if len(parts) == 2:
129
137
  proto, valu = parts
@@ -1296,6 +1296,11 @@ class ItModule(s_module.CoreModule):
1296
1296
  ('net6', ('inet:net6', {}), {
1297
1297
  'doc': 'The optional contiguous IPv6 address range of this network.'}),
1298
1298
 
1299
+ ('dns:resolvers', ('array', {'type': 'inet:server',
1300
+ 'typeopts': {'defport': 53, 'defproto': 'udp'},
1301
+ 'sorted': True, 'uniq': True}), {
1302
+ 'doc': 'An array of DNS servers configured to resolve requests for hosts on the network.'})
1303
+
1299
1304
  )),
1300
1305
  ('it:account', {}, (
1301
1306
  ('user', ('inet:user', {}), {
synapse/models/telco.py CHANGED
@@ -193,6 +193,11 @@ class TelcoModule(s_module.CoreModule):
193
193
  'doc': 'A mobile cell site which a phone may connect to.'
194
194
  }),
195
195
 
196
+ # TODO - eventually break out ISO-3 country code into a sub
197
+ # https://en.wikipedia.org/wiki/TADIG_code
198
+ ('tel:mob:tadig', ('str', {'regex': '^[A-Z0-9]{5}$', 'strip': True}), {
199
+ 'doc': 'A Transferred Account Data Interchange Group number issued to a GSM carrier.'}),
200
+
196
201
  ),
197
202
 
198
203
  'forms': (
@@ -322,6 +327,9 @@ class TelcoModule(s_module.CoreModule):
322
327
  ('loc', ('loc', {}), {
323
328
  'doc': 'Location the carrier operates from.'
324
329
  }),
330
+
331
+ ('tadig', ('tel:mob:tadig', {}), {
332
+ 'doc': 'The TADIG code issued to the carrier.'}),
325
333
  )),
326
334
  ('tel:mob:cell', {}, (
327
335
  ('carrier', ('tel:mob:carrier', {}), {'doc': 'Mobile carrier.', 'ro': True, }),
@@ -340,6 +348,8 @@ class TelcoModule(s_module.CoreModule):
340
348
  'doc': 'The place associated with the latlong property.'}),
341
349
  )),
342
350
 
351
+ ('tel:mob:tadig', {}, ()),
352
+
343
353
  ('tel:mob:telem', {}, (
344
354
 
345
355
  ('time', ('time', {}), {}),