From 19e171612119c670822d6cc41377a7703e44e636 Mon Sep 17 00:00:00 2001 From: "max.mehl" Date: Thu, 3 Mar 2022 10:58:48 +0100 Subject: [PATCH] generalise setup of peers, both for machines and manually defined users --- deploy.yml | 11 +++++ group_vars/all.yml | 9 +++- roles/client/tasks/add_peer_server.yml | 26 +++++++++++ roles/client/tasks/main.yml | 63 ++++++++++---------------- roles/server/tasks/main.yml | 27 +++++++++-- 5 files changed, 92 insertions(+), 44 deletions(-) create mode 100644 roles/client/tasks/add_peer_server.yml diff --git a/deploy.yml b/deploy.yml index 7ebcbd3..1cc3243 100644 --- a/deploy.yml +++ b/deploy.yml @@ -3,6 +3,17 @@ # SPDX-License-Identifier: AGPL-3.0-or-later --- +- hosts: all + remote_user: root + tags: [peers] + tasks: + - name: Get innernet-server hostname from inventory groups + set_fact: + # Assuming that we only have one innernet server, we take the first + # occurence + innernet_server: "{{ groups['innernet_server'][0] }}" + run_once: true + - hosts: innernet_server remote_user: root roles: diff --git a/group_vars/all.yml b/group_vars/all.yml index 87f14e3..c38b682 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -43,14 +43,21 @@ cidrs: # so automatically configured peers (typically VMs) machine_cidr: machines +# Peers that are configured manually, typically humans. The created invitation +# file will be stored on the controller machines and has to be imported on the +# person's computer manually. 'name' must consist of alphanumeric characters and +# dashes, no dots or similar! manual_peers: linus: + name: linus cidr: admins admin: true - max-mehl: + max.mehl: + name: max-mehl cidr: admins admin: true albert: + name: albert cidr: admins admin: true diff --git a/roles/client/tasks/add_peer_server.yml b/roles/client/tasks/add_peer_server.yml new file mode 100644 index 0000000..9fb9d35 --- /dev/null +++ b/roles/client/tasks/add_peer_server.yml @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: 2021 Free Software Foundation Europe +# +# SPDX-License-Identifier: AGPL-3.0-or-later +--- +- name: Add innernet peer on server + shell: | + innernet-server add-peer "{{ network_name }}" \ + --name "{{ peer_name }}" \ + --cidr "{{ peer_cidr }}" \ + --admin "{{ peer_admin | lower }}" \ + --save-config "/root/{{ peer_name }}.toml" \ + --invite-expires "14d" \ + --auto-ip \ + --yes + +- name: Copy peer invitation file from server to controller + fetch: + src: "/root/{{ peer_name }}.toml" + dest: "{{ playbook_dir }}/roles/client/files/{{ peer_name }}.toml" + flat: yes + fail_on_missing: yes + +- name: Delete peer invitation file on server + file: + state: absent + path: "/root/{{ peer_name }}.toml" diff --git a/roles/client/tasks/main.yml b/roles/client/tasks/main.yml index 93db997..3c47058 100644 --- a/roles/client/tasks/main.yml +++ b/roles/client/tasks/main.yml @@ -3,13 +3,6 @@ # SPDX-License-Identifier: AGPL-3.0-or-later --- -- name: Get innernet-server hostname from inventory groups - set_fact: - # Assuming that we only have one innernet server, we take the first - # occurence - innernet_server: "{{ groups['innernet_server'][0] }}" - run_once: true - - name: Convert hostname to innernet peer name tags: [peers] # we want the mere host name before the domain, so e.g. @@ -25,12 +18,6 @@ - ['-fsfe-org', ''] - ['-fsfe-be', ''] -- name: Get existing peers from innernet-server database - tags: [peers] - shell: 'sqlite3 /var/lib/innernet-server/{{ network_name }}.db "select name from peers;"' - register: existing_peers - delegate_to: "{{ innernet_server }}" - - name: Gather which packages are installed on the client tags: [update] package_facts: @@ -68,29 +55,31 @@ # If 1. innernet not installed or 2. `update` tag executed when: "'innernet' not in ansible_facts.packages or 'update' in ansible_run_tags" -- name: Make client a new innernet peer +- name: Get existing peers from innernet-server database + shell: 'sqlite3 /var/lib/innernet-server/{{ network_name }}.db "select name from peers;"' + register: existing_peers + delegate_to: "{{ innernet_server }}" + run_once: true + +- name: Add machine as innernet peer + tags: [peers] + include_tasks: add_peer_server.yml + args: + apply: + tags: [peers] + delegate_to: "{{ innernet_server }}" + vars: + peer_name: "{{ innernet_client }}" + # Value of the CIDR we defined as the CIDR for machines + peer_cidr: "{{ cidrs[machine_cidr]['name'] }}" + # machines are never admins + peer_admin: "false" + when: + - innernet_client not in existing_peers.stdout_lines + +- name: Install innernet peer invitation on machine tags: [peers] block: - - name: Add client as innernet peer - shell: | - innernet-server add-peer "{{ network_name }}" \ - --name "{{ innernet_client }}" \ - --cidr "{{ cidrs[machine_cidr]['cidr'] }}" \ - --admin "false" \ - --save-config "/root/{{ innernet_client }}.toml" \ - --invite-expires "14d" \ - --auto-ip \ - --yes - delegate_to: "{{ innernet_server }}" - - - name: Copy peer invitation file from server to controller - fetch: - src: "/root/{{ innernet_client }}.toml" - dest: "{{ playbook_dir }}/roles/client/files/{{ innernet_client }}.toml" - flat: yes - fail_on_missing: yes - delegate_to: "{{ innernet_server }}" - - name: Copy peer invitation file from controller to client copy: src: "{{ innernet_client }}.toml" @@ -106,12 +95,6 @@ file: state: absent path: "/root/{{ innernet_client }}.toml" - - - name: Delete peer invitation file from server - file: - state: absent - path: "/root/{{ innernet_client }}.toml" - delegate_to: "{{ innernet_server }}" when: - innernet_client not in existing_peers.stdout_lines diff --git a/roles/server/tasks/main.yml b/roles/server/tasks/main.yml index bcb332d..01b8e38 100644 --- a/roles/server/tasks/main.yml +++ b/roles/server/tasks/main.yml @@ -68,13 +68,35 @@ tags: [cidr] shell: | innernet-server add-cidr "{{ network_name }}" \ - --name "{{ item.name }}" \ + --name "{{ item.value.name }}" \ --parent "{{ item.value.parent }}" \ --cidr "{{ item.value.cidr }}" \ --yes loop: "{{ cidrs | dict2items }}" when: - - item.key not in existing_cidrs.stdout_lines + - item.value.name not in existing_cidrs.stdout_lines + +# Configure manually defined peers (mostly humans) +- name: Get existing peers from innernet-server database + shell: 'sqlite3 /var/lib/innernet-server/{{ network_name }}.db "select name from peers;"' + register: existing_peers + run_once: true + +- name: Add manually defined peers + tags: [peers] + include_role: + name: client + tasks_from: add_peer_server + args: + apply: + tags: [peers] + vars: + peer_name: "{{ item.value.name }}" + peer_cidr: "{{ item.value.cidr }}" + peer_admin: "{{ item.value.admin }}" + loop: "{{ manual_peers | dict2items }}" + when: + - item.value.name not in existing_peers.stdout_lines - name: Enable firewall and allow SSH tags: [listen_port, firewall] @@ -89,7 +111,6 @@ ufw: to_port: "{{ network_listen_port }}" rule: allow - proto: udp - name: Restart and enable innernet-server daemon systemd: