Let adapter plugins provide configured endpoints
This commit is contained in:
@@ -8,6 +8,7 @@ from unittest.mock import patch
|
||||
|
||||
from dns_sync.adapters import Endpoint
|
||||
from dns_sync.registry import (
|
||||
configured_adapter_endpoints,
|
||||
enabled_plugins,
|
||||
load_adapter,
|
||||
)
|
||||
@@ -221,5 +222,291 @@ class PluginRegistryTests(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
|
||||
def test_builtin_adapter_supplies_configured_endpoints(self):
|
||||
endpoint = Endpoint(
|
||||
"npm",
|
||||
"192.168.1.3:81",
|
||||
)
|
||||
config = SimpleNamespace(
|
||||
npm_endpoints=(endpoint,),
|
||||
)
|
||||
|
||||
with patch.dict(
|
||||
os.environ,
|
||||
{
|
||||
"ENABLED_PLUGINS": "npm",
|
||||
},
|
||||
clear=True,
|
||||
):
|
||||
endpoints = configured_adapter_endpoints(
|
||||
"npm",
|
||||
config,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
endpoints,
|
||||
(endpoint,),
|
||||
)
|
||||
|
||||
|
||||
def test_external_adapter_cache_respects_plugin_root(self):
|
||||
with tempfile.TemporaryDirectory() as first_directory, \
|
||||
tempfile.TemporaryDirectory() as second_directory:
|
||||
|
||||
first_root = Path(first_directory)
|
||||
second_root = Path(second_directory)
|
||||
|
||||
first_plugin = first_root / "example_cache"
|
||||
second_plugin = second_root / "example_cache"
|
||||
|
||||
first_plugin.mkdir()
|
||||
second_plugin.mkdir()
|
||||
|
||||
first_plugin.joinpath("__init__.py").write_text(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
from dns_sync.adapters import Endpoint
|
||||
|
||||
|
||||
def configured_endpoints(config):
|
||||
return (
|
||||
Endpoint(
|
||||
"example_cache",
|
||||
"first.example:443",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class Plugin:
|
||||
name = "example_cache"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config,
|
||||
endpoint,
|
||||
):
|
||||
self.endpoint = endpoint
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
second_plugin.joinpath("__init__.py").write_text(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
from dns_sync.adapters import Endpoint
|
||||
|
||||
|
||||
def configured_endpoints(config):
|
||||
return (
|
||||
Endpoint(
|
||||
"example_cache",
|
||||
"second.example:443",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class Plugin:
|
||||
name = "example_cache"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config,
|
||||
endpoint,
|
||||
):
|
||||
self.endpoint = endpoint
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
with patch.dict(
|
||||
os.environ,
|
||||
{
|
||||
"ENABLED_PLUGINS": "example_cache",
|
||||
"DNS_SYNC_PLUGIN_PATH": first_directory,
|
||||
},
|
||||
clear=True,
|
||||
):
|
||||
first = configured_adapter_endpoints(
|
||||
"example_cache",
|
||||
SimpleNamespace(),
|
||||
)
|
||||
|
||||
with patch.dict(
|
||||
os.environ,
|
||||
{
|
||||
"ENABLED_PLUGINS": "example_cache",
|
||||
"DNS_SYNC_PLUGIN_PATH": second_directory,
|
||||
},
|
||||
clear=True,
|
||||
):
|
||||
second = configured_adapter_endpoints(
|
||||
"example_cache",
|
||||
SimpleNamespace(),
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
tuple(endpoint.identity for endpoint in first),
|
||||
("example_cache://first.example:443",),
|
||||
)
|
||||
self.assertEqual(
|
||||
tuple(endpoint.identity for endpoint in second),
|
||||
("example_cache://second.example:443",),
|
||||
)
|
||||
|
||||
|
||||
def test_external_adapter_supplies_configured_endpoints(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
plugin = root / "example"
|
||||
plugin.mkdir()
|
||||
|
||||
(plugin / "__init__.py").write_text(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
import os
|
||||
|
||||
from dns_sync.adapters import Endpoint
|
||||
|
||||
|
||||
def configured_endpoints(config):
|
||||
address = os.environ["EXAMPLE_ENDPOINT"]
|
||||
return (
|
||||
Endpoint("example", address),
|
||||
)
|
||||
|
||||
|
||||
class Plugin:
|
||||
name = "example"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config,
|
||||
endpoint,
|
||||
):
|
||||
self.config = config
|
||||
self.endpoint = endpoint
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
with patch.dict(
|
||||
os.environ,
|
||||
{
|
||||
"ENABLED_PLUGINS": "example",
|
||||
"DNS_SYNC_PLUGIN_PATH": directory,
|
||||
"EXAMPLE_ENDPOINT": "example.test:9443",
|
||||
},
|
||||
clear=True,
|
||||
):
|
||||
endpoints = configured_adapter_endpoints(
|
||||
"example",
|
||||
SimpleNamespace(),
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
tuple(
|
||||
endpoint.identity
|
||||
for endpoint in endpoints
|
||||
),
|
||||
("example://example.test:9443",),
|
||||
)
|
||||
|
||||
|
||||
def test_adapter_missing_endpoint_hook_fails_closed(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
plugin = root / "example_missing_hook"
|
||||
plugin.mkdir()
|
||||
|
||||
(plugin / "__init__.py").write_text(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
class Plugin:
|
||||
name = "example_missing_hook"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config,
|
||||
endpoint,
|
||||
):
|
||||
self.config = config
|
||||
self.endpoint = endpoint
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
with patch.dict(
|
||||
os.environ,
|
||||
{
|
||||
"ENABLED_PLUGINS": "example_missing_hook",
|
||||
"DNS_SYNC_PLUGIN_PATH": directory,
|
||||
},
|
||||
clear=True,
|
||||
):
|
||||
with self.assertRaisesRegex(
|
||||
RuntimeError,
|
||||
"does not export configured_endpoints",
|
||||
):
|
||||
configured_adapter_endpoints(
|
||||
"example_missing_hook",
|
||||
SimpleNamespace(),
|
||||
)
|
||||
|
||||
|
||||
def test_adapter_endpoint_hook_cannot_cross_plugin_boundary(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
plugin = root / "example_wrong_endpoint"
|
||||
plugin.mkdir()
|
||||
|
||||
(plugin / "__init__.py").write_text(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
from dns_sync.adapters import Endpoint
|
||||
|
||||
|
||||
def configured_endpoints(config):
|
||||
return (
|
||||
Endpoint(
|
||||
"other",
|
||||
"example.test:443",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class Plugin:
|
||||
name = "example_wrong_endpoint"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config,
|
||||
endpoint,
|
||||
):
|
||||
self.config = config
|
||||
self.endpoint = endpoint
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
with patch.dict(
|
||||
os.environ,
|
||||
{
|
||||
"ENABLED_PLUGINS": "example_wrong_endpoint",
|
||||
"DNS_SYNC_PLUGIN_PATH": directory,
|
||||
},
|
||||
clear=True,
|
||||
):
|
||||
with self.assertRaisesRegex(
|
||||
RuntimeError,
|
||||
"returned endpoint for plugin",
|
||||
):
|
||||
configured_adapter_endpoints(
|
||||
"example_wrong_endpoint",
|
||||
SimpleNamespace(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user