support moving interfaces into default netns

Closes #23.
main v2.3.2
UpYoursMicrosoft 2 months ago committed by dadevel
parent b84edfd253
commit 150a052211
No known key found for this signature in database
GPG Key ID: 1A8A9735430193D5

@ -63,9 +63,9 @@ Minimal JSON example:
Full YAML example:
~~~ yaml
# name of the network namespace
# name of the network namespace where the interface is moved into, if null the default namespace is used
name: ns-example
# namespace where the interface is initialized, defaults to the main/default namespace
# namespace where the interface is initialized, if null the default namespace is used
base_netns: null
# if false, the netns itself won't be created or deleted, just the interfaces inside it
managed: true

@ -1,6 +1,6 @@
[tool.poetry]
name = "wgnetns"
version = "2.3.1"
version = "2.3.2"
description = "wg-quick for network namespaces"
authors = ["dadevel <dadevel@disroot.org>"]
license = "MIT"

@ -15,6 +15,7 @@ try:
YAML_SUPPORTED = True
except ModuleNotFoundError:
YAML_SUPPORTED = False
yaml = NotImplemented
WIREGUARD_DIR = Path('/etc/wireguard')
NETNS_DIR = Path('/etc/netns')
@ -172,17 +173,17 @@ class Interface:
if self.private_key:
wg('set', self.name, 'private-key', '/dev/stdin', stdin=self.private_key, netns=self.base_netns)
def _assign_namespace(self, namespace: str) -> None:
ip('link', 'set', self.name, 'netns', namespace, netns=self.base_netns)
def _assign_namespace(self, namespace: str|None) -> None:
ip('link', 'set', self.name, 'netns', namespace if namespace else '1', netns=self.base_netns)
def _assign_addresses(self, namespace: str) -> None:
def _assign_addresses(self, namespace: str|None) -> None:
for address in self.address:
ip('-6' if ':' in address else '-4', 'address', 'add', address, 'dev', self.name, netns=namespace)
def _bring_up(self, namespace: str) -> None:
def _bring_up(self, namespace: str|None) -> None:
ip('link', 'set', 'dev', self.name, 'mtu', self.mtu, 'up', netns=namespace)
def _create_routes(self, namespace: str):
def _create_routes(self, namespace: str|None):
for peer in self.peers:
networks = peer.routes if peer.routes is not None else peer.allowed_ips
for network in networks:
@ -217,8 +218,8 @@ class ScriptletItem:
host_namespace = bool(data.pop('host_namespace', None))
return cls(**data, host_namespace=host_namespace)
def run(self, netns: str):
if self.host_namespace:
def run(self, netns: str|None):
if self.host_namespace or not netns:
host_eval(self.command)
else:
ip_netns_eval(self.command, netns=netns)
@ -247,14 +248,14 @@ class Scriptlet:
item = ScriptletItem.from_str(data)
return cls(items=[item])
def run(self, netns: str):
def run(self, netns: str|None):
for item in self.items:
item.run(netns=netns)
@dataclasses.dataclass
class Namespace:
name: str
name: str|None
pre_up: Optional[Scriptlet] = None
post_up: Optional[Scriptlet] = None
pre_down: Optional[Scriptlet] = None
@ -302,7 +303,7 @@ class Namespace:
return cls(**data, **scriptlets, interfaces=interfaces) # type: ignore
def setup(self) -> Namespace:
if self.managed:
if self.managed and self.name:
self._create()
self._write_resolvconf()
if self.pre_up:
@ -338,6 +339,7 @@ class Namespace:
@property
def _resolvconf_path(self) -> Path:
assert self.name
return NETNS_DIR/self.name/'resolv.conf'
def _write_resolvconf(self) -> None:
@ -370,8 +372,8 @@ def ip_netns_exec(*args, netns: str, stdin: str|None = None, check=True, capture
return ip('netns', 'exec', netns, *args, stdin=stdin, check=check, capture=capture)
def ip(*args, stdin: str|None = None, netns=None, check=True, capture=False) -> str:
return run('ip', *([] if netns is None else ['-n', netns]), *args, stdin=stdin, check=check, capture=capture)
def ip(*args, stdin: str|None = None, netns: str|None =None, check=True, capture=False) -> str:
return run('ip', *(['-n', netns] if netns else []), *args, stdin=stdin, check=check, capture=capture)
def host_eval(*args, stdin: str|None = None, check=True, capture=False) -> str:

Loading…
Cancel
Save