aiomisc 17.5.29__tar.gz → 17.5.31__tar.gz
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.
- {aiomisc-17.5.29 → aiomisc-17.5.31}/PKG-INFO +1 -1
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/dns/records.py +1 -1
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/dns/store.py +20 -1
- aiomisc-17.5.31/aiomisc/service/dns/zone.py +67 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/raven.py +2 -2
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/version.py +2 -2
- {aiomisc-17.5.29 → aiomisc-17.5.31}/pyproject.toml +1 -1
- aiomisc-17.5.29/aiomisc/service/dns/zone.py +0 -44
- {aiomisc-17.5.29 → aiomisc-17.5.31}/COPYING +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/README.rst +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/__init__.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/_context_vars.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/aggregate.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/backoff.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/circuit_breaker.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/compat.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/context.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/counters.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/cron.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/entrypoint.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/io.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/iterator_wrapper.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/log.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/periodic.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/plugins/__init__.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/plugins/__main__.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/pool.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/process_pool.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/py.typed +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/recurring.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/__init__.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/aiohttp.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/asgi.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/base.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/carbon.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/cron.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/dns/__init__.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/dns/service.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/dns/tree.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/grpc_server.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/periodic.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/process.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/profiler.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/sdwatchdog.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/tcp.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/tls.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/tracer.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/udp.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/service/uvicorn.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/signal.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/thread_pool.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/timeout.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/utils.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc/worker_pool.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/__init__.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/enum.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/formatter/__init__.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/formatter/color.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/formatter/journald.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/formatter/json.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/formatter/rich.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_log/py.typed +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/__init__.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/__main__.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/forking.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/process.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/process_inner.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/protocol.py +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/py.typed +0 -0
- {aiomisc-17.5.29 → aiomisc-17.5.31}/aiomisc_worker/worker.py +0 -0
@@ -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
|
@@ -0,0 +1,67 @@
|
|
1
|
+
from collections import defaultdict
|
2
|
+
from typing import DefaultDict, Iterable, Sequence, Set, Tuple
|
3
|
+
|
4
|
+
from .records import DNSRecord, RecordType
|
5
|
+
|
6
|
+
|
7
|
+
RecordsType = DefaultDict[Tuple[str, RecordType], Set[DNSRecord]]
|
8
|
+
|
9
|
+
|
10
|
+
class DNSZone:
|
11
|
+
records: RecordsType
|
12
|
+
name: str
|
13
|
+
|
14
|
+
__slots__ = ("name", "records")
|
15
|
+
|
16
|
+
def __init__(self, name: str, *records: DNSRecord) -> None:
|
17
|
+
if not name.endswith("."):
|
18
|
+
name += "."
|
19
|
+
self.name = name
|
20
|
+
self.records = defaultdict(set)
|
21
|
+
|
22
|
+
for record in records:
|
23
|
+
self.add_record(record)
|
24
|
+
|
25
|
+
def add_record(self, record: DNSRecord) -> None:
|
26
|
+
if not self.check_record(record):
|
27
|
+
raise ValueError(
|
28
|
+
f"Record {record.name} does not belong to zone {self.name}",
|
29
|
+
)
|
30
|
+
self.records[(record.name, record.type)].add(record)
|
31
|
+
|
32
|
+
def remove_record(self, record: DNSRecord) -> None:
|
33
|
+
key = (record.name, record.type)
|
34
|
+
if key in self.records:
|
35
|
+
self.records[key].discard(record)
|
36
|
+
if self.records[key]:
|
37
|
+
return
|
38
|
+
del self.records[key]
|
39
|
+
|
40
|
+
def get_records(
|
41
|
+
self, name: str, record_type: RecordType,
|
42
|
+
) -> Sequence[DNSRecord]:
|
43
|
+
if not name.endswith("."):
|
44
|
+
name += "."
|
45
|
+
return tuple(self.records.get((name, record_type), ()))
|
46
|
+
|
47
|
+
def check_record(self, record: DNSRecord) -> bool:
|
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
|
@@ -70,7 +70,7 @@ class AioHttpTransportBase(
|
|
70
70
|
def __init__(
|
71
71
|
self, parsed_url: Optional[str] = None, *, verify_ssl: bool = True,
|
72
72
|
timeout: TimeoutType = defaults.TIMEOUT, keepalive: bool = True,
|
73
|
-
family:
|
73
|
+
family: socket.AddressFamily = socket.AddressFamily.AF_INET,
|
74
74
|
):
|
75
75
|
self._keepalive = keepalive
|
76
76
|
self._family = family
|
@@ -92,7 +92,7 @@ class AioHttpTransportBase(
|
|
92
92
|
return self._keepalive
|
93
93
|
|
94
94
|
@property
|
95
|
-
def family(self) ->
|
95
|
+
def family(self) -> socket.AddressFamily:
|
96
96
|
return self._family
|
97
97
|
|
98
98
|
def _client_session_factory(self) -> aiohttp.ClientSession:
|
@@ -1,7 +1,7 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "aiomisc"
|
3
3
|
# This is a dummy version which will be rewritten with poem-plugins
|
4
|
-
version = "17.5.
|
4
|
+
version = "17.5.31"
|
5
5
|
description = "aiomisc - miscellaneous utils for asyncio"
|
6
6
|
authors = ["Dmitry Orlov <me@mosquito.su>"]
|
7
7
|
readme = "README.rst"
|
@@ -1,44 +0,0 @@
|
|
1
|
-
from collections import defaultdict
|
2
|
-
from typing import DefaultDict, Sequence, Set, Tuple
|
3
|
-
|
4
|
-
from .records import DNSRecord, RecordType
|
5
|
-
|
6
|
-
|
7
|
-
class DNSZone:
|
8
|
-
records: DefaultDict[Tuple[str, RecordType], Set[DNSRecord]]
|
9
|
-
name: str
|
10
|
-
|
11
|
-
__slots__ = ("name", "records")
|
12
|
-
|
13
|
-
def __init__(self, name: str):
|
14
|
-
if not name.endswith("."):
|
15
|
-
name += "."
|
16
|
-
self.name = name
|
17
|
-
self.records = defaultdict(set)
|
18
|
-
|
19
|
-
def add_record(self, record: DNSRecord) -> None:
|
20
|
-
if not self._is_valid_record(record):
|
21
|
-
raise ValueError(
|
22
|
-
f"Record {record.name} does not belong to zone {self.name}",
|
23
|
-
)
|
24
|
-
key = (record.name, record.type)
|
25
|
-
self.records[key].add(record)
|
26
|
-
|
27
|
-
def remove_record(self, record: DNSRecord) -> None:
|
28
|
-
key = (record.name, record.type)
|
29
|
-
if key in self.records:
|
30
|
-
self.records[key].discard(record)
|
31
|
-
if self.records[key]:
|
32
|
-
return
|
33
|
-
del self.records[key]
|
34
|
-
|
35
|
-
def get_records(
|
36
|
-
self, name: str, record_type: RecordType,
|
37
|
-
) -> Sequence[DNSRecord]:
|
38
|
-
if not name.endswith("."):
|
39
|
-
name += "."
|
40
|
-
key = (name, record_type)
|
41
|
-
return tuple(self.records.get(key, ()))
|
42
|
-
|
43
|
-
def _is_valid_record(self, record: DNSRecord) -> bool:
|
44
|
-
return record.name.endswith(self.name)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|