diff --git a/bundlewrap/bundles/mixer-to-encoder-ssh-login/items.py b/bundlewrap/bundles/mixer-to-encoder-ssh-login/items.py new file mode 100644 index 00000000..06cb2e35 --- /dev/null +++ b/bundlewrap/bundles/mixer-to-encoder-ssh-login/items.py @@ -0,0 +1,10 @@ +if node.metadata.get('users/voc/ssh_config_verbatim/mixer-to-encoder-ssh-login', set()): + files['/home/voc/.ssh/mixer-to-encoder-ssh-login'] = { + 'content': repo.libs.ssh.generate_ed25519_private_key('voc', node), + 'owner': 'voc', + 'mode': '0600', + } +else: + files['/home/voc/.ssh/mixer-to-encoder-ssh-login'] = { + 'delete': True, + } diff --git a/bundlewrap/bundles/mixer-to-encoder-ssh-login/metadata.py b/bundlewrap/bundles/mixer-to-encoder-ssh-login/metadata.py new file mode 100644 index 00000000..6522f811 --- /dev/null +++ b/bundlewrap/bundles/mixer-to-encoder-ssh-login/metadata.py @@ -0,0 +1,33 @@ +from bundlewrap.exceptions import NoSuchGroup + +@metadata_reactor.provides( + 'users/voc/ssh_config_verbatim/mixer-to-encoder-ssh-login', +) +def ssh_config_generator(metadata): + room_number = metadata.get('room_number', None) + if room_number is None: + return {} + + try: + saal_nodes = repo.nodes_in_group(f'saal{room_number}') + except NoSuchGroup: + return {} + + ssh_hostnames = set() + for rnode in saal_nodes: + if rnode.name == node.name: + continue + + ssh_hostnames.add(rnode.name) + ssh_hostnames.add(rnode.hostname) + ssh_hostnames.add(rnode.metadata.get('hostname')) + + return { + 'users': { + 'voc': { + 'ssh_config_verbatim': { + 'mixer-to-encoder-ssh-login': ssh_hostnames, + }, + }, + }, + } diff --git a/bundlewrap/bundles/users/items.py b/bundlewrap/bundles/users/items.py index f9ce418b..e5d49855 100644 --- a/bundlewrap/bundles/users/items.py +++ b/bundlewrap/bundles/users/items.py @@ -43,7 +43,7 @@ if 'ssh_pubkeys' in attrs: files[home + '/.ssh/authorized_keys'] = { - 'content': '\n'.join(sorted(attrs['ssh_pubkeys'])) + '\n', + 'content': repo.libs.faults.join_faults(sorted(attrs['ssh_pubkeys']), '\n') + '\n', 'owner': username, 'mode': '0600', } @@ -61,6 +61,10 @@ if exists(join(repo.path, 'data', 'users', 'files', ftype, username)): files[f'{home}/{fname}'] = { 'source': f'{ftype}/{username}', + 'content_type': 'mako', + 'context': { + 'verbatim_config': node.metadata.get(f'users/{username}/{ftype}_verbatim', {}), + }, } else: files[f'{home}/{fname}'] = { diff --git a/bundlewrap/bundles/users/metadata.py b/bundlewrap/bundles/users/metadata.py index 4a6562ef..2bd53a49 100644 --- a/bundlewrap/bundles/users/metadata.py +++ b/bundlewrap/bundles/users/metadata.py @@ -2,7 +2,7 @@ from os import environ from os.path import dirname, join -from bundlewrap.exceptions import BundleError +from bundlewrap.exceptions import BundleError, NoSuchGroup defaults = { 'apt': { @@ -18,7 +18,7 @@ 'cascade_skip': False, }, 'voc': { - 'password': repo.vault.decrypt('encrypt$gAAAAABkNXrxKojy17G1rsgYSYEd_jkJ_GcTcqLFgWFKgWb3hpNnQ1YHpps-iICtfzXrgjK7Kaf18YWW-N94SRZ9tiKLSSiPWA=='), + 'password': repo.vault.human_password_for(f'{node.name} user voc'), 'cascade_skip': False, }, }, @@ -101,3 +101,32 @@ def user_voc(metadata): }, }, } + + +@metadata_reactor.provides( + 'users/voc/ssh_pubkeys', +) +def mixer_to_encoder_ssh_login(metadata): + room_number = metadata.get('room_number', None) + if room_number is None: + return {} + + try: + saal_nodes = repo.nodes_in_group(f'saal{room_number}') + except NoSuchGroup: + return {} + + pubkeys = set() + for rnode in saal_nodes: + if not rnode.has_bundle('mixer-to-encoder-ssh-login'): + continue + + pubkeys.add(repo.libs.ssh.generate_ed25519_public_key('voc', rnode)) + + return { + 'users': { + 'voc': { + 'ssh_pubkeys': pubkeys, + }, + }, + } diff --git a/bundlewrap/data/users/files/ssh_config/voc b/bundlewrap/data/users/files/ssh_config/voc index 0273386e..4867a0b2 100644 --- a/bundlewrap/data/users/files/ssh_config/voc +++ b/bundlewrap/data/users/files/ssh_config/voc @@ -7,3 +7,9 @@ Host releasing.c3voc.de IdentityFile /home/voc/.ssh/upload-key StrictHostKeyChecking accept-new User upload +% if 'mixer-to-encoder-ssh-login' in verbatim_config: + +Host ${' '.join(sorted(verbatim_config['mixer-to-encoder-ssh-login']))} + IdentityFile /home/voc/.ssh/mixer-to-encoder-ssh-login + StrictHostKeyChecking accept-new +% endif diff --git a/bundlewrap/groups/roles.py b/bundlewrap/groups/roles.py index aea634c4..d01dd472 100644 --- a/bundlewrap/groups/roles.py +++ b/bundlewrap/groups/roles.py @@ -28,6 +28,7 @@ }, 'bundles': { 'mixer-common', + 'mixer-to-encoder-ssh-login', 'voctogui', 'voctomix2', },