From 28332d389dd3644aeb3973d4ca472820f6b45b07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Romain=20Gon=C3=A7alves?= <me@rgoncalves.se>
Date: Fri, 13 Jan 2023 00:15:52 +0100
Subject: feat(roles/relayd): add argument specs

---
 roles/relayd/defaults/main.yml        | 12 ++++++++--
 roles/relayd/handlers/main.yml        |  4 ----
 roles/relayd/meta/main.yml            | 45 +++++++++++++++++++++++++++++++++++
 roles/relayd/tasks/main.yml           | 18 +++++++++++---
 roles/relayd/templates/relayd.conf.j2 | 38 +++++++++++++----------------
 5 files changed, 87 insertions(+), 30 deletions(-)
 delete mode 100644 roles/relayd/handlers/main.yml
 create mode 100644 roles/relayd/meta/main.yml

(limited to 'roles/relayd')

diff --git a/roles/relayd/defaults/main.yml b/roles/relayd/defaults/main.yml
index 66eef3b..2028ef1 100644
--- a/roles/relayd/defaults/main.yml
+++ b/roles/relayd/defaults/main.yml
@@ -3,6 +3,14 @@
 relayd_rules: {}
 
 relayd_configuration_file: /etc/relayd.conf
-relayd_domain_name: example.com
-relayd_transparent: true
 relayd_block_msg: aah!
+
+relayd_tls_ciphers:
+  - HIGH
+  - "!AES128"
+  - "!kRSA"
+  - "!aNULL"
+relayd_tls_elliptic_curves:
+  - P-384
+  - P-256
+  - X25519
diff --git a/roles/relayd/handlers/main.yml b/roles/relayd/handlers/main.yml
deleted file mode 100644
index 58e1171..0000000
--- a/roles/relayd/handlers/main.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-
-- name: lint relayd configuration
-  ansible.builtin.command: "relayd -nf {{ relayd_configuration_file }}"
diff --git a/roles/relayd/meta/main.yml b/roles/relayd/meta/main.yml
new file mode 100644
index 0000000..e2da9c2
--- /dev/null
+++ b/roles/relayd/meta/main.yml
@@ -0,0 +1,45 @@
+---
+
+argument_specs:
+  main:
+    short_description: relayd main entrypoint.
+    options:
+
+      relayd_rules:
+        type: list
+        elements: dict
+        required: true
+        options:
+          domain:
+            type: str
+            required: true
+            description: Domain name
+          name:
+            type: str
+            required: true
+            description: Rule name
+          port:
+            type: int
+            required: true
+            description: Port to be configured
+
+      relayd_configuration_file:
+        type: path
+        required: true
+        description: Relayd configuration file
+
+      relayd_domain_name:
+        type: str
+        required: true
+        description: Relayd domain name
+
+      relayd_connected_hosts:
+        type: str
+        required: true
+        description: Group name of hosts that are behind relayd
+
+      relayd_tls_ciphers:
+        type: list
+        elements: str
+        required: true
+        description: Relayd tls ciphers
diff --git a/roles/relayd/tasks/main.yml b/roles/relayd/tasks/main.yml
index e8e18a3..8dc2837 100644
--- a/roles/relayd/tasks/main.yml
+++ b/roles/relayd/tasks/main.yml
@@ -7,11 +7,23 @@
     owner: 0
     group: 0
     mode: "0640"
-  notify:
-    - lint relayd configuration
+  register: relayd_result_generate_configuration
 
-- name: enable and restart relayd
+- name: lint relayd configuration
+  ansible.builtin.command: "relayd -nf {{ relayd_configuration_file }}"
+  register: relayd_result_lint_configuration
+  changed_when:
+    - relayd_result_generate_configuration.changed
+    - relayd_result_lint_configuration.rc != 0
+
+- name: restart relayd  # noqa: no-handler
   ansible.builtin.service:
     name: relayd
     state: restarted
+  when: relayd_result_generate_configuration.changed
+    or relayd_result_lint_configuration.changed
+
+- name: enable relayd
+  ansible.builtin.service:
+    name: relayd
     enabled: true
diff --git a/roles/relayd/templates/relayd.conf.j2 b/roles/relayd/templates/relayd.conf.j2
index b66ffa7..67b9e13 100644
--- a/roles/relayd/templates/relayd.conf.j2
+++ b/roles/relayd/templates/relayd.conf.j2
@@ -6,10 +6,11 @@ log connection errors
 
 # hosts
 table <local> { 127.0.0.1 }
-{% call(h) macros.loop_valid_hosts("servers") -%}
-table <{{ h.inventory_hostname }}> { {{ h.__ip.internal }} }
-{% for name, rules in h.relayd_rules.items() if rules.domain is defined %}
-table <{{ h.inventory_hostname }}_{{ rules.domain }}> { {{ h.__ip.internal }} }
+{% call(h) macros.loop_valid_hosts(relayd_connected_hosts) -%}
+{% set relayd_rule_ip = "127.0.0.1" if h.inventory_hostname == inventory_hostname else h.__ip.internal %}
+table <{{ h.inventory_hostname }}> { {{ relayd_rule_ip }} }
+{% for rule in h.relayd_rules %}
+table <{{ h.inventory_hostname }}_{{ rule.name }}> { {{ relayd_rule_ip }} }
 {% endfor %}
 {%- endcall %}
 
@@ -17,8 +18,8 @@ table <{{ h.inventory_hostname }}_{{ rules.domain }}> { {{ h.__ip.internal }} }
 
 http protocol "https" {
 	
-	tls ciphers "HIGH:!AES128:!kRSA:!aNULL"
-	tls ecdhe "P-384,P-256,X25519"
+	tls ciphers "{{ relayd_tls_ciphers | join(':') }}"
+	tls ecdhe "{{ relayd_tls_elliptic_curves | join(',') }}"
 
 	tcp { sack, backlog 128 }
 
@@ -31,13 +32,10 @@ http protocol "https" {
 	match response header set "Referrer-Policy" value "no-referrer"
 	match response header set "X-XSS-Protection" value "1; mode=block"
 
-	tls keypair "{{ relayd_domain_name }}"
-	pass request quick header "Host" value "{{ relayd_domain_name }}" forward to <local>
-{% call(h) macros.loop_valid_hosts("servers") -%}
-{% for name, rules in h.relayd_rules.items() if rules.domain is defined %}
-	{% set domain_name = rules.domain ~ "." ~ relayd_domain_name -%}
-	tls keypair "{{ domain_name }}"
-	pass request quick header "Host" value "{{ domain_name }}" forward to <{{ h.inventory_hostname }}_{{ rules.domain }}>
+{% call(h) macros.loop_valid_hosts(relayd_connected_hosts) -%}
+{% for rule in h.relayd_rules %}
+	tls keypair "{{ rule.domain }}"
+	pass request quick header "Host" value "{{ rule.domain }}" forward to <{{ h.inventory_hostname }}_{{ rule.name }}>
 {% endfor %}
 {%- endcall %}
 
@@ -50,11 +48,9 @@ http protocol "http" {
 	# acme
 	pass request quick path "/.well-known/acme-challenge/*" forward to <local>
 
-	pass request quick header "Host" value "{{ relayd_domain_name }}" forward to <local>
-{% call(h) macros.loop_valid_hosts("servers") -%}
-{% for name, rules in h.relayd_rules.items() if rules.domain is defined %}
-	{% set domain_name = rules.domain ~ "." ~ relayd_domain_name -%}
-	pass request quick header "Host" value "{{ domain_name }}" forward to <{{ h.inventory_hostname }}_{{ rules.domain }}>
+{% call(h) macros.loop_valid_hosts(relayd_connected_hosts) -%}
+{% for rule in h.relayd_rules %}
+	pass request quick header "Host" value "{{ rule.domain }}" forward to <{{ h.inventory_hostname }}_{{ rule.name }}>
 {% endfor %}
 {%- endcall %}
 
@@ -74,9 +70,9 @@ relay "wwwtls" {
 	listen on egress port 443 tls
 	protocol "https"
 	forward to <local> port 80 check http "/" code 200
-{% call(h) macros.loop_valid_hosts("servers") -%}
-{% for name, rules in h.relayd_rules.items() if rules.domain is defined %}
-	forward to <{{ h.inventory_hostname }}_{{ rules.domain }}> port {{ rules.port }} check tcp
+{% call(h) macros.loop_valid_hosts(relayd_connected_hosts) -%}
+{% for rule in h.relayd_rules %}
+	forward to <{{ h.inventory_hostname }}_{{ rule.name }}> port {{ rule.port }} check tcp
 {% endfor %}
 {%- endcall %}
 }
-- 
cgit v1.2.3