Skip to content

Commit b590255

Browse files
committed
added perun_sync
1 parent 4a16ecd commit b590255

9 files changed

Lines changed: 183 additions & 9 deletions

File tree

defaults/main.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,15 @@ perun_msmtp_config: |
706706
user test
707707
password test
708708
709+
# Perun-to-Perun synchronization
710+
perun_sync_enabled: no
711+
perun_sync_users:
712+
- user: perunsync
713+
group: perunsync
714+
comment: Perun-to-Perun synchronization
715+
src_host: idm.ics.muni.cz
716+
ssh_key_file: files/idm.ics.muni.cz/id_rsa.pub
717+
709718
######################
710719
# You do not need to modify values below
711720
######################

files/perun_sync.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env python3
2+
import grp
3+
import os
4+
import pwd
5+
import sys
6+
import json
7+
8+
DIR = os.getenv('HOME')
9+
RESOURCE_ATTR_NAME = "urn:perun:resource:attribute-def:def:authorizationResourceId"
10+
11+
def update_json(data):
12+
for user_uuid, user_data in data["users"].items():
13+
allowed_resources_uuids = list(user_data.get("allowed_resources", {}).keys())
14+
for resource_uuid in allowed_resources_uuids:
15+
if resource_uuid in data["resources"]:
16+
data["resources"].setdefault(resource_uuid, {}).setdefault("members", {})
17+
data["resources"][resource_uuid]["members"][user_uuid] = user_data["attributes"]
18+
data["users"][user_uuid].pop("allowed_resources", None)
19+
return data
20+
21+
22+
def remove_unmatched_files(data):
23+
all_resources_names = []
24+
for resource_uuid, resource_data in data["resources"].items():
25+
all_resources_names.append(resource_data["attributes"][RESOURCE_ATTR_NAME])
26+
27+
for filename in os.listdir(DIR):
28+
if filename.endswith(".json") and filename.split(".json")[0] not in all_resources_names:
29+
filepath = os.path.join(DIR, filename)
30+
os.remove(filepath)
31+
32+
33+
def replace_files(data):
34+
for resource_uuid, resource_data in data["resources"].items():
35+
resource_name = resource_data["attributes"][RESOURCE_ATTR_NAME]
36+
filepath = os.path.join(DIR, resource_name)
37+
with open(f"{filepath}.tmp", "w") as tmp_file:
38+
json.dump(resource_data, tmp_file, indent=4)
39+
tmp_file.flush()
40+
os.fsync(tmp_file.fileno())
41+
# uid = pwd.getpwnam("perunrpc").pw_uid
42+
# gid = grp.getgrnam("perunrpc").gr_gid
43+
# os.chown(f"{filepath}.tmp", uid, gid)
44+
os.replace(f"{filepath}.tmp", f"{filepath}.json")
45+
46+
47+
if __name__ == "__main__":
48+
if len(sys.argv) != 2:
49+
print("Usage: python script.py <file_path>")
50+
sys.exit(1)
51+
52+
# Load JSON from file
53+
file_path = sys.argv[1]
54+
55+
with open(file_path, "r") as f:
56+
data = json.load(f)
57+
58+
data = update_json(data)
59+
remove_unmatched_files(data)
60+
replace_files(data)

tasks/main.yml

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,24 @@
33
assert:
44
that:
55
- ansible_version is defined
6-
- ansible_version.full is version_compare('2.14.3', '>=')
7-
msg: "Required version is 2.14.3, this is {{ ansible_version.full }}"
6+
- ansible_version.full is version_compare('2.16.4', '>=')
7+
msg: "Required version is 2.16.4, this is {{ ansible_version.full }}"
88
quiet: true
99
tags: always
1010

1111
- name: "Collection community.general version check ({{ lookup('community.general.collection_version', 'community.general') }})"
1212
assert:
1313
that:
14-
- lookup('community.general.collection_version', 'community.general') is version('6.4.0','>=')
15-
msg: "Required version is 6.4.0, this is {{lookup('community.general.collection_version', 'community.general') }}"
14+
- lookup('community.general.collection_version', 'community.general') is version('8.4.0','>=')
15+
msg: "Required version is 8.4.0, this is {{lookup('community.general.collection_version', 'community.general') }}"
16+
quiet: true
17+
tags: always
18+
19+
- name: "Collection community.docker version check ({{ lookup('community.general.collection_version', 'community.docker') }})"
20+
assert:
21+
that:
22+
- lookup('community.general.collection_version', 'community.docker') is version('3.8.0','>=')
23+
msg: "Required version is 3.8.0, this is {{lookup('community.general.collection_version', 'community.docker') }}"
1624
quiet: true
1725
tags: always
1826

@@ -187,6 +195,16 @@
187195
- site_specific
188196
- site_specific_before
189197

198+
- name: "setup of Perun-to-Perun synchronization"
199+
when: perun_sync_enabled
200+
include_tasks:
201+
file: perun_sync.yml
202+
apply:
203+
tags:
204+
- perun_sync
205+
tags:
206+
- perun_sync
207+
190208
- name: "perun rpc setup"
191209
import_tasks: perun_rpc.yml
192210
tags:

tasks/perun_apache.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,9 @@
423423
- name: perun_net
424424
network_mode: perun_net
425425
etc_hosts: "{{ perun_containers_etc_hosts | combine( { 'perun-host': perun_net_info.network.IPAM.Config[0].Gateway }) }}"
426-
container_default_behavior: no_defaults
426+
image_name_mismatch: recreate
427+
comparisons:
428+
'*': strict
427429
ports:
428430
- 80:80
429431
- 443:443

tasks/perun_auditlogger.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@
125125
- name: perun_net
126126
network_mode: perun_net
127127
etc_hosts: "{{ perun_containers_etc_hosts | combine( { 'perun-host': perun_net_info.network.IPAM.Config[0].Gateway }) }}"
128-
container_default_behavior: no_defaults
128+
image_name_mismatch: recreate
129+
comparisons:
130+
'*': strict
129131
state: "{{ 'started' if perun_auditlogger_enabled else 'absent' }}"
130132
register: perun_auditlogger_container
131133

tasks/perun_engine.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,9 @@
329329
- name: perun_net
330330
network_mode: perun_net
331331
etc_hosts: "{{ perun_containers_etc_hosts | combine( { 'perun-host': perun_net_info.network.IPAM.Config[0].Gateway }) }}"
332-
container_default_behavior: no_defaults
332+
image_name_mismatch: recreate
333+
comparisons:
334+
'*': strict
333335
state: "{{ 'started' if perun_engine_enabled else 'absent' }}"
334336
register: perun_engine_container
335337

tasks/perun_ldapc.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@
122122
- name: perun_net
123123
network_mode: perun_net
124124
etc_hosts: "{{ perun_containers_etc_hosts | combine( { 'perun-host': perun_net_info.network.IPAM.Config[0].Gateway }) }}"
125-
container_default_behavior: no_defaults
125+
image_name_mismatch: recreate
126+
comparisons:
127+
'*': strict
126128
state: "{{ 'started' if perun_ldapc_enabled else 'absent' }}"
127129
register: perun_ldapc_container
128130

tasks/perun_rpc.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@
237237
set_fact:
238238
rpc_mounts: "{{ rpc_mounts + perun_rpc_mounts_additional }}"
239239

240+
- name: "add sync dirs to perun_rpc mounts"
241+
when: perun_sync_enabled
242+
loop: "{{ perun_sync_users }}"
243+
loop_control:
244+
label: "/home/{{ item.user }}"
245+
set_fact:
246+
rpc_mounts: "{{ rpc_mounts + [ { 'type': 'bind', 'source': '/home/' + item.user, 'target': '/home/' + item.user } ] }}"
247+
240248
- name: "get perun_net info"
241249
docker_network_info:
242250
name: perun_net
@@ -262,7 +270,9 @@
262270
memory: "{{ (ansible_memtotal_mb * 0.6)|int }}M"
263271
#memory_swap: "{{ (ansible_memtotal_mb * 0.6)|int }}M"
264272
#memory_swappiness: 0
265-
container_default_behavior: no_defaults
273+
image_name_mismatch: recreate
274+
comparisons:
275+
'*': strict
266276
register: perun_rpc_container
267277

268278
- name: "remove old hostname"

tasks/perun_sync.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
- name: "install perun slave scripts for receiving from Peruns"
2+
apt:
3+
name:
4+
- perun-slave-base
5+
- perun-slave-process-generic-json-gen
6+
state: present
7+
8+
- name: "allow propagation to {{ perun_instance_hostname }}"
9+
copy:
10+
dest: /etc/perunv3.conf
11+
content: |
12+
DNS_ALIAS_WHITELIST=( {{ perun_instance_hostname }} )
13+
14+
- name: "create /etc/perun/generic_json_gen.d/pre_10_set_script"
15+
copy:
16+
dest: /etc/perun/generic_json_gen.d/pre_10_set_script
17+
content: |
18+
#!/bin/bash
19+
export DST_SCRIPT="/opt/perun/perun_sync.py"
20+
21+
- name: "create /opt/perun/perun_sync.py"
22+
copy:
23+
dest: /opt/perun/perun_sync.py
24+
src: perun_sync.py
25+
owner: root
26+
group: root
27+
mode: '0755'
28+
29+
- name: "create groups for each source Perun"
30+
loop: "{{ perun_sync_users }}"
31+
group:
32+
name: "{{ item.group }}"
33+
34+
- name: "create users for each source Perun"
35+
loop: "{{ perun_sync_users }}"
36+
user:
37+
name: "{{ item.user }}"
38+
group: "{{ item.group }}"
39+
comment: "{{ item.comment }}"
40+
shell: /bin/bash
41+
create_home: true
42+
43+
- name: "add source Perun's engine ssh keys"
44+
loop: "{{ perun_sync_users }}"
45+
authorized_key:
46+
exclusive: true
47+
user: "{{ item.user }}"
48+
key_options: 'from="{{ item.src_host }}",command="/opt/perun/bin/perun"'
49+
key: "{{ lookup('ansible.builtin.file', item.ssh_key_file ) }}"
50+
51+
- name: "allow UseDNS for sshd"
52+
lineinfile:
53+
path: /etc/ssh/sshd_config
54+
regexp: 'UseDNS'
55+
line: 'UseDNS yes'
56+
register: sshd_config
57+
58+
- name: "restart sshd"
59+
when: sshd_config.changed
60+
systemd:
61+
name: sshd
62+
state: reloaded
63+
64+
- name: "add perunrpc to groups for sync"
65+
loop: "{{ perun_sync_users }}"
66+
user:
67+
name: perunrpc
68+
groups: "{{ item.group }}"
69+
append: true

0 commit comments

Comments
 (0)