aiomisc 17.5.30__py3-none-any.whl → 17.5.31__py3-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.
@@ -1,4 +1,4 @@
1
- from typing import Optional, Sequence, Tuple
1
+ from typing import Iterable, Mapping, Optional, Sequence, Tuple
2
2
 
3
3
  from .records import DNSRecord, RecordType
4
4
  from .tree import RadixTree
@@ -49,3 +49,22 @@ class DNSStore:
49
49
  @staticmethod
50
50
  def get_reverse_tuple(zone_name: str) -> Tuple[str, ...]:
51
51
  return tuple(zone_name.strip(".").split("."))[::-1]
52
+
53
+ def replace(
54
+ self, zones_data: Mapping[str, Iterable[DNSRecord]],
55
+ ) -> None:
56
+ """
57
+ Atomically replace all zones with new ones this method is safe
58
+ because it replaces all zones at once. zone_data is a mapping
59
+ zone name and a sequence of DNSRecord objects.
60
+
61
+ If any of the zones or records is invalid, nothing will be replaced.
62
+
63
+ This method is useful for reload configuration from disk
64
+ or database or etc.
65
+ """
66
+ new_zones: RadixTree[DNSZone] = RadixTree()
67
+ for zone_name, records in zones_data.items():
68
+ zone = DNSZone(zone_name, *records)
69
+ new_zones.insert(self.get_reverse_tuple(zone.name), zone)
70
+ self.zones = new_zones
@@ -1,28 +1,33 @@
1
1
  from collections import defaultdict
2
- from typing import DefaultDict, Sequence, Set, Tuple
2
+ from typing import DefaultDict, Iterable, Sequence, Set, Tuple
3
3
 
4
4
  from .records import DNSRecord, RecordType
5
5
 
6
6
 
7
+ RecordsType = DefaultDict[Tuple[str, RecordType], Set[DNSRecord]]
8
+
9
+
7
10
  class DNSZone:
8
- records: DefaultDict[Tuple[str, RecordType], Set[DNSRecord]]
11
+ records: RecordsType
9
12
  name: str
10
13
 
11
14
  __slots__ = ("name", "records")
12
15
 
13
- def __init__(self, name: str):
16
+ def __init__(self, name: str, *records: DNSRecord) -> None:
14
17
  if not name.endswith("."):
15
18
  name += "."
16
19
  self.name = name
17
20
  self.records = defaultdict(set)
18
21
 
22
+ for record in records:
23
+ self.add_record(record)
24
+
19
25
  def add_record(self, record: DNSRecord) -> None:
20
- if not self._is_valid_record(record):
26
+ if not self.check_record(record):
21
27
  raise ValueError(
22
28
  f"Record {record.name} does not belong to zone {self.name}",
23
29
  )
24
- key = (record.name, record.type)
25
- self.records[key].add(record)
30
+ self.records[(record.name, record.type)].add(record)
26
31
 
27
32
  def remove_record(self, record: DNSRecord) -> None:
28
33
  key = (record.name, record.type)
@@ -37,8 +42,26 @@ class DNSZone:
37
42
  ) -> Sequence[DNSRecord]:
38
43
  if not name.endswith("."):
39
44
  name += "."
40
- key = (name, record_type)
41
- return tuple(self.records.get(key, ()))
45
+ return tuple(self.records.get((name, record_type), ()))
42
46
 
43
- def _is_valid_record(self, record: DNSRecord) -> bool:
47
+ def check_record(self, record: DNSRecord) -> bool:
44
48
  return record.name.endswith(self.name)
49
+
50
+ def replace(self, records: Iterable[DNSRecord]) -> None:
51
+ """
52
+ Atomically replace all records in specified zone with new ones.
53
+ This method is safe because it replaces all records at once.
54
+
55
+ If any of the records does not belong to the zone, ValueError
56
+ will be raised and no records will be replaced.
57
+ """
58
+ new_records: RecordsType = defaultdict(set)
59
+
60
+ for record in records:
61
+ if not self.check_record(record):
62
+ raise ValueError(
63
+ f"Record {record.name} does not "
64
+ f"belong to zone {self.name}",
65
+ )
66
+ new_records[(record.name, record.type)].add(record)
67
+ self.records = new_records
aiomisc/version.py CHANGED
@@ -2,5 +2,5 @@
2
2
  # BY: poem-plugins "git" plugin
3
3
  # NEVER EDIT THIS FILE MANUALLY
4
4
 
5
- version_info = (17, 5, 30)
6
- __version__ = "17.5.30"
5
+ version_info = (17, 5, 31)
6
+ __version__ = "17.5.31"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aiomisc
3
- Version: 17.5.30
3
+ Version: 17.5.31
4
4
  Summary: aiomisc - miscellaneous utils for asyncio
5
5
  Home-page: https://github.com/aiokitchen/aiomisc
6
6
  License: MIT
@@ -27,9 +27,9 @@ aiomisc/service/cron.py,sha256=VM-FjdAhy_zFkU-YTdpBSxF79upvrsCo-3kdI9cZTOo,1975
27
27
  aiomisc/service/dns/__init__.py,sha256=RT8_0H8LrQe8sz2xvA2BvLi6CiJVZeVFltNRAx9MN7o,254
28
28
  aiomisc/service/dns/records.py,sha256=VE65kDSJ3Fg3-V60-AQQY2OxR89_ggaAc38k7vKUatM,8771
29
29
  aiomisc/service/dns/service.py,sha256=F8KSmFry6WpA4tWNrKcXVhS6GWb_Cyl3uanGu4lbOPw,3616
30
- aiomisc/service/dns/store.py,sha256=FchfLSoWAI2x4n5RyIcnx_i7RQjHmBbco4L4rSAanGU,1749
30
+ aiomisc/service/dns/store.py,sha256=PCYp-H1UoFzUVaYfSnK78_TG3fw1CeIzg-ndMgu_cE4,2509
31
31
  aiomisc/service/dns/tree.py,sha256=q9VRcVxggrClUHyGZZqqSByMaHdU4nYPC1NdT17cVWM,1575
32
- aiomisc/service/dns/zone.py,sha256=Dc3bL7L3rz38J0_R790d_uJlisfJ78vwfdsxmtVfg_w,1343
32
+ aiomisc/service/dns/zone.py,sha256=6Xmrl_leLalSiRQWWNuwGtZVw31Y93i9K2j0JU1vt-4,2174
33
33
  aiomisc/service/grpc_server.py,sha256=G1iRGX3jAfv3fpzNnw_n6UuhORmIZK4cz6aAi7t7qcU,4553
34
34
  aiomisc/service/periodic.py,sha256=BEKGWxWDOX11sfo7MFYp-hiB5iZ4-c2BRsjS56k5B-0,1241
35
35
  aiomisc/service/process.py,sha256=mZf8muZJNWQo95pUmzchMk08MJMhLifFK8m4CnNX49k,4477
@@ -45,7 +45,7 @@ aiomisc/signal.py,sha256=_iiC2jukXg7-LLirIl1YATlKIIsKLbmTNFr1Ezheu7g,1728
45
45
  aiomisc/thread_pool.py,sha256=591u5HV1aBmBRcaVm4kAtMLPZOb6veqhT9wkts_knqE,14017
46
46
  aiomisc/timeout.py,sha256=OhXCvQGbPZA9IQ7cRT7ZlZnsbmDgH5ioErQyjeqIEzY,919
47
47
  aiomisc/utils.py,sha256=6yTfTpeRCVzfZp-MJCmB1oayOHUBVwQwzC3U5PBAjn8,11919
48
- aiomisc/version.py,sha256=v0ByhEcfvGAR6tx57WupDPQW31oDea5ompia7i31xFk,156
48
+ aiomisc/version.py,sha256=inQlcadD8kWvAqeup4DUVRxcUEOCEEwskUqD2Cu1nXM,156
49
49
  aiomisc/worker_pool.py,sha256=GA91KdOrBlqHthbVSTxu_d6BsBIbl-uKqW2NxqSafG0,11107
50
50
  aiomisc_log/__init__.py,sha256=ZD-Q-YTWoZdxJpMqMNMIraA_gaN0QawgnVpXz6mxd2o,4855
51
51
  aiomisc_log/enum.py,sha256=_zfCZPYCGyI9KL6TqHiYVlOfA5U5MCbsuCuDKxDHdxg,1549
@@ -63,8 +63,8 @@ aiomisc_worker/process_inner.py,sha256=8ZtjCSLrgySW57OIbuGrpEWxfysRLYKx1or1YaAqx
63
63
  aiomisc_worker/protocol.py,sha256=1smmlBbdreSmnrxuhHaUMUC10FO9xMIEcedhweQJX_A,2705
64
64
  aiomisc_worker/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  aiomisc_worker/worker.py,sha256=f8nCFhlKh84UUBUaEgCllwMRvVZiD8_UUXaeit6g3T8,3236
66
- aiomisc-17.5.30.dist-info/COPYING,sha256=Ky_8CQMaIixfyOreUBsl0hKN6A5fLnPF8KPQ9molMYA,1125
67
- aiomisc-17.5.30.dist-info/METADATA,sha256=yCZt7Tn4_yEzDoa6C5euBj1hai0BYG5fjo9y9aPu9VI,15724
68
- aiomisc-17.5.30.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
69
- aiomisc-17.5.30.dist-info/entry_points.txt,sha256=KRsSPCwKJyGTWrvzpwbS0yIDwzsgDA2X6f0CBWYmNao,55
70
- aiomisc-17.5.30.dist-info/RECORD,,
66
+ aiomisc-17.5.31.dist-info/COPYING,sha256=Ky_8CQMaIixfyOreUBsl0hKN6A5fLnPF8KPQ9molMYA,1125
67
+ aiomisc-17.5.31.dist-info/METADATA,sha256=4Mvo60Wnj7oJLOqGnrPrbiIGcSEiKY1HHCTj5dVHqa0,15724
68
+ aiomisc-17.5.31.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
69
+ aiomisc-17.5.31.dist-info/entry_points.txt,sha256=KRsSPCwKJyGTWrvzpwbS0yIDwzsgDA2X6f0CBWYmNao,55
70
+ aiomisc-17.5.31.dist-info/RECORD,,