2
0
mirror of https://github.com/dadevel/wg-netns synced 2024-10-30 21:20:12 +00:00

add list and switch commands

This commit is contained in:
dadevel 2022-10-17 20:59:12 +02:00
parent 2542d9f4cd
commit 41665ca136
No known key found for this signature in database
GPG Key ID: 1A8A9735430193D5
2 changed files with 22 additions and 2 deletions

View File

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

View File

@ -4,6 +4,7 @@ from argparse import ArgumentParser, RawDescriptionHelpFormatter
from pathlib import Path from pathlib import Path
from typing import Any, Optional from typing import Any, Optional
import dataclasses import dataclasses
import itertools
import json import json
import os import os
import subprocess import subprocess
@ -58,6 +59,11 @@ def cli(args):
parser.add_argument('-f', '--force', action='store_true', help='ignore errors') parser.add_argument('-f', '--force', action='store_true', help='ignore errors')
parser.add_argument('profile', type=lambda x: Path(x).expanduser(), metavar='PROFILE', help='name or path of profile') parser.add_argument('profile', type=lambda x: Path(x).expanduser(), metavar='PROFILE', help='name or path of profile')
parser = subparsers.add_parser('list', help='list network namespaces')
parser = subparsers.add_parser('switch', help='open shell in namespace')
parser.add_argument('netns', metavar='NETNS', help='network namespace name')
opts = entrypoint.parse_args(args) opts = entrypoint.parse_args(args)
try: try:
@ -68,8 +74,9 @@ def cli(args):
except Exception as e: except Exception as e:
raise RuntimeError(f'failed to load environment variable: {e} (e.__class__.__name__)') from e raise RuntimeError(f'failed to load environment variable: {e} (e.__class__.__name__)') from e
namespace = Namespace.from_profile(opts.profile)
if opts.action == 'up': if opts.action == 'up':
_conditional_elevate()
namespace = Namespace.from_profile(opts.profile)
try: try:
namespace.setup() namespace.setup()
except KeyboardInterrupt: except KeyboardInterrupt:
@ -78,11 +85,24 @@ def cli(args):
namespace.teardown(check=False) namespace.teardown(check=False)
raise raise
elif opts.action == 'down': elif opts.action == 'down':
_conditional_elevate()
namespace = Namespace.from_profile(opts.profile)
namespace.teardown(check=not opts.force) namespace.teardown(check=not opts.force)
elif opts.action == 'list':
output = ip('-json', 'netns', capture=True)
data = json.loads(output)
print('\n'.join(item['name'] for item in data))
elif opts.action == 'switch':
os.execvp('sudo', ['ip', 'ip', 'netns', 'exec', opts.netns, 'sudo', '-u', os.getlogin(), '-D', Path.cwd().as_posix(), os.environ['SHELL'], '-i'])
else: else:
raise RuntimeError('congratulations, you reached unreachable code') raise RuntimeError('congratulations, you reached unreachable code')
def _conditional_elevate() -> None:
if os.getuid() != 0 and os.isatty(sys.stdin.fileno()):
os.execvp('sudo', [sys.argv[0], *sys.argv])
@dataclasses.dataclass @dataclasses.dataclass
class Peer: class Peer:
public_key: str public_key: str