diff --git a/lustmolch.py b/lustmolch.py index 3a6d738330c341e764e62911e453a5223ca8ddc2..f671b10455b4d6bbacd55ad9282a90328643b157 100755 --- a/lustmolch.py +++ b/lustmolch.py @@ -43,7 +43,10 @@ IP_SUBNET_LENGTH = 30 def gen_default_conf(): - return {} + return { + 'users': {}, + 'containers': {} + } def get_config(file_path): @@ -68,11 +71,11 @@ def next_ssh_port(cfg, name): Returns: SSH port """ - if name in cfg: - return cfg[name].get('ssh_port') + if name in cfg['containers']: + return cfg['containers'][name].get('ssh_port') port = SSH_START_PORT - for container in cfg.values(): + for container in cfg['containers'].values(): if container['ssh_port'] >= port: port = container['ssh_port'] + SSH_PORT_INCREMENT @@ -90,16 +93,16 @@ def next_ip_address(cfg, name): Returns (tuple): host_ip, container_ip """ - if name in cfg: - c = cfg[name] + if name in cfg['containers']: + c = cfg['containers'][name] return (c.get('ip_address_host').split('/')[0], c.get('ip_address_container').split('/')[0]) ip_host = list(IP_START_HOST) container_ips = [container['ip_address_host'].split('/')[0].split('.') - for container in cfg.values()] - print(container_ips) + for container in cfg['containers'].values()] + ip_host[2] = max([int(ip[2]) for ip in container_ips]) ip_host[3] = max([int(ip[3]) for ip in container_ips]) ip_host[3] += 4 @@ -123,12 +126,12 @@ def update_config(config_file, container): if not Path(config_file).exists(): with open(config_file, 'w+') as f: cfg = gen_default_conf() - cfg[container['name']] = container + cfg['containers'][container['name']] = container json.dump(cfg, f, indent=4) else: with open(config_file, 'r') as f: cfg = json.load(f) - cfg[container['name']] = container + cfg['containers'][container['name']] = container with open(config_file, 'w') as f: json.dump(cfg, f, indent=4) @@ -147,7 +150,7 @@ def cli(): def list_containers(config_file): cfg = get_config(config_file) - click.echo('Currently registered containers\n') + click.echo('Currently registered containers:\n') click.echo(json.dumps(cfg, indent=4)) @@ -178,7 +181,8 @@ def create_container(dry_run, config_file, name): 'ip_address_host': ip_address_host, 'ip_address_container': ip_address_container, 'ip_subnet_length': IP_SUBNET_LENGTH, - 'url': f'{name}.stusta.de' + 'url': f'{name}.stusta.de', + 'users': [] } click.echo(f'Generated context values for container: {repr(context)}') @@ -253,6 +257,67 @@ def create_container(dry_run, config_file, name): 'To finish please run "iptables-save".') +@cli.command() +@click.option( + '--config-file', + default=DEFAULT_CONF_FILE, + help='Container configuration file') +@click.option('--key-string', is_flag=True, default=False) +@click.argument('name') +@click.argument('key') +def add_user(config_file, key_string, name, key): + if key_string: + key_string = key + else: + with open(key, 'r') as f: + key_string = f.read() + cfg = get_config(config_file) + + cfg['users'][name] = { + 'name': name, + 'key': key + } + + with open(config_file, 'w') as f: + json.dump(cfg, f, indent=4) + + +@cli.command() +@click.option( + '--config-file', + default=DEFAULT_CONF_FILE, + help='Container configuration file') +@click.argument('name') +def remove_user(config_file, name) + cfg = get_config(config_file) + if name in cfg['users']: + del cfg['users'][name] + + with open(config_file, 'w') as f: + json.dump(cfg, f, indent=4) + + +@cli.command() +@click.option('--dry-run', is_flag=True, default=False) +@click.option( + '--config-file', + default=DEFAULT_CONF_FILE, + help='Container configuration file') +def update_containers(dry_run, config_file): + cfg = get_config(config_file) + + for container in cfg['containers'].values(): + ssh_dir = Path('/var/lib/machines', container['name'], 'root/.ssh') + authorized_keys = ssh_dir / 'authorized_keys' + + keys = '\n'.join([user['key'] if user['name'] in container['users'] for user in cfg['users']]) + click.echo(f'Writing\n\n{keys}\n to authorized key file {authorized_keys}') + if not dry_run: + ssh_dir.mkdir(mode=0o700, parents=True, exist_ok=True) + authorized_keys.touch(mode=0o600, exist_ok=True) + authorized_keys.write_text(keys) + + @cli.command() @click.option( '--config-file', @@ -262,6 +327,7 @@ def create_container(dry_run, config_file, name): @click.argument('name') @click.argument('key') def install_ssh_key(config_file, key_string, name, key): + click.echo('DEPRECATED: Use add-user, update-contaienrs instead. Will be removed soon!') ssh_dir = Path('/var/lib/machines', name, 'root/.ssh') authorized_keys = ssh_dir / 'authorized_keys' if key_string: