From 09a7451a78d1375b8be17a7dd274fb32a466867f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Th=C3=A9o=20-=20Le=20Filament?= <theo@le-filament.com>
Date: Thu, 21 Nov 2024 16:26:56 +0100
Subject: [PATCH] feat: allow to define custom ssh host and private key for git
 usage

---
 files/ssh_config        |  3 --
 tasks/main.yml          | 84 ++++++++++++++++++++---------------------
 templates/Dockerfile.j2 |  7 +---
 templates/ssh_config.j2 |  5 +++
 4 files changed, 48 insertions(+), 51 deletions(-)
 delete mode 100644 files/ssh_config
 create mode 100644 templates/ssh_config.j2

diff --git a/files/ssh_config b/files/ssh_config
deleted file mode 100644
index 8177128..0000000
--- a/files/ssh_config
+++ /dev/null
@@ -1,3 +0,0 @@
-Host sources.le-filament.com
-    IdentityFile ~root/.ssh/id_ed25519.sources
-    IdentitiesOnly yes
diff --git a/tasks/main.yml b/tasks/main.yml
index e958544..e26159f 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -55,74 +55,74 @@
     test_instance_need_build
     and test_instance_is_selected
 
-- name: Copy private GitLab ssh keys file
-  ansible.builtin.copy:
-    content: "{{ git_modules_privkey | default('') }}"
-    dest: "/home/docker/{{ odoo_instance.key }}/odoo/id_ed25519.sources"
-    owner: root
-    group: root
-    mode: '0400'
+- name: "Create `dot_ssh` dir in Odoo docker build directories on server in /home/docker/<instance>/odoo/dot_ssh"
+  ansible.builtin.file:
+    name: "/home/docker/{{ odoo_instance.key }}/odoo/dot_ssh"
+    state: directory
+    owner: "root"
+    group: "root"
+    mode: "0500"
   loop: "{{ odoo_instances | dict2items }}"
   loop_control:
     label: "{{ odoo_instance.key }}"
   when: >
     test_instance_need_build
     and test_instance_is_selected
-  register: result
-  notify:
-    - "remove intermediate images"
+    and git_ssh_private_keys is defined
 
-# notify:
-#   - "rebuild odoo image"
-#   - "remove ssh private keys"
-- name: "Add instance to rebuild and remove key lists if files was changed"
-  set_fact:
-    instances_to_rebuild: "{{ instances_to_rebuild + [item.item.key] }}"
-    instances_to_remove_key: "{{ instances_to_remove_key + [item.item.key] }}"
-  loop: "{{ result.results | flatten(levels=1) }}"
-  loop_control:
-    label: "{{ item.item.key }}"
-  when: test_result_item_has_changed
-
-- name: Copy ssh config for connecting to LF Gitlab
+- name: "Copy private SSH keys file"
+  tags:
+    - "git_ssh_keys"
+  vars:
+    item: "{{ item_instance_sshkey.0 }}"
   ansible.builtin.copy:
-    src: ssh_config
-    dest: "/home/docker/{{ odoo_instance.key }}/odoo/ssh_config"
+    content: "{{ item_instance_sshkey.1.value.private_key }}"
+    dest: "/home/docker/{{ item_instance_sshkey.0.key }}/odoo/dot_ssh/{{ item_instance_sshkey.1.key }}"
     owner: root
     group: root
-    mode: '0444'
-  loop: "{{ odoo_instances | dict2items }}"
+    mode: '0400'
+  loop: "{{ odoo_instances | dict2items | product(git_ssh_private_keys | dict2items) }}"
   loop_control:
-    label: "{{ odoo_instance.key }}"
+    label: "{{ item_instance_sshkey.0.key }}: SSH key '{{ item_instance_sshkey.1.key }}'"
+    loop_var: item_instance_sshkey
   when: >
     test_instance_need_build
     and test_instance_is_selected
+    and git_ssh_private_keys is defined
   register: result
+  notify:
+    - "remove intermediate images"
 
 # notify:
 #   - "rebuild odoo image"
-- name: "Add instance to rebuild list if files was changed"
+#   - "remove ssh private keys"
+- name: "Add instance to rebuild and remove key lists if files was changed"
   set_fact:
-    instances_to_rebuild: "{{ instances_to_rebuild + [item.item.key] }}"
+    instances_to_rebuild: "{{ instances_to_rebuild + [item.item_instance_sshkey.0.key] }}"
+    instances_to_remove_key: "{{ instances_to_remove_key + [item.item_instance_sshkey.0.key] }}"
   loop: "{{ result.results | flatten(levels=1) }}"
   loop_control:
-    label: "{{ item.item.key }}"
-  when: test_result_item_has_changed
+    label: "{{ item.item_instance_sshkey.0.key }}"
+  when: item.changed
 
-- name: Copy private Git ssh keys file
-  ansible.builtin.copy:
-    content: "{{ git_private_keys }}"
-    dest: "/home/docker/{{ odoo_instance.key }}/odoo/id_rsa"
-    owner: root
-    group: root
-    mode: '0400'
+- name: "Copy ssh config for connecting to git repositories"
+  tags:
+    - "git_ssh_keys"
+  vars:
+    template_git_ssh_private_keys: "{{ git_ssh_private_keys }}"
+  ansible.builtin.template:
+    src: "ssh_config.j2"
+    dest: "/home/docker/{{ odoo_instance.key }}/odoo/dot_ssh/config"
+    owner: "root"
+    group: "root"
+    mode: "0400"
   loop: "{{ odoo_instances | dict2items }}"
   loop_control:
     label: "{{ odoo_instance.key }}"
   when: >
-    git_private_keys is defined
-    and test_instance_need_build
+    test_instance_need_build
     and test_instance_is_selected
+    and git_ssh_private_keys is defined
   register: result
 
 # notify:
@@ -285,7 +285,7 @@
 
 - name: "Remove instances private keys"
   ansible.builtin.file:
-    path: "/home/docker/{{ odoo_instance.key }}/odoo/id_ed25519.sources"
+    path: "/home/docker/{{ odoo_instance.key }}/odoo/dot_ssh"
     state: absent
   loop: "{{ instances_to_remove_key | unique | sort }}"
   when: >
diff --git a/templates/Dockerfile.j2 b/templates/Dockerfile.j2
index 23fead8..f46824c 100644
--- a/templates/Dockerfile.j2
+++ b/templates/Dockerfile.j2
@@ -10,12 +10,7 @@ LABEL stage=builder
 USER root
 
 # Install GitLab private keys
-COPY ./id_ed25519.sources /root/.ssh/
-COPY ./ssh_config /root/.ssh/config
-{% if git_private_keys is defined %}
-# Install private keys
-COPY ./id_rsa /root/.ssh/
-{% endif %}
+COPY ./dot_ssh/* /root/.ssh
 
 # Add addons.
 ARG SAVE_COMMITS_FILENAME='custom_addons'
diff --git a/templates/ssh_config.j2 b/templates/ssh_config.j2
new file mode 100644
index 0000000..f2520e0
--- /dev/null
+++ b/templates/ssh_config.j2
@@ -0,0 +1,5 @@
+{% for template_item in (template_git_ssh_private_keys | dict2items) %}
+Host {{ template_item.value.host }}
+    IdentityFile ~root/.ssh/{{ template_item.key }}
+    IdentitiesOnly yes
+{% endfor %}
-- 
GitLab