From ce7903e43aa3f99c449892e5401065175b48eec7 Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Fri, 1 Mar 2024 08:43:15 +0100 Subject: [PATCH] ceph: improve cluster setup Remove separate NetBox lookups. Explicitly allow connections between cluster nodes. Tigthen temporary allowed IPv6 ranges. --- filter_plugins/netbox.py | 15 +++++++++++++++ inventory.yml | 2 ++ roles/ceph/tasks/main.yml | 12 ++++++------ roles/ceph/templates/hosts.j2 | 7 +++---- roles/ceph/templates/nftables.conf.j2 | 27 ++++++++++++++++++++++----- 5 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 filter_plugins/netbox.py diff --git a/filter_plugins/netbox.py b/filter_plugins/netbox.py new file mode 100644 index 0000000..db0c629 --- /dev/null +++ b/filter_plugins/netbox.py @@ -0,0 +1,15 @@ +#!/usr/bin/python + +class FilterModule(object): + '''Various utilities for manipulating NetBox data''' + def filters(self): + return { + 'device_address': self.device_address + } + + def device_address(self, device): + '''Return loopback IP addresses for an L3 attached device''' + for iface in device['interfaces']: + for addr in iface['ip_addresses']: + if addr.get('role') and addr['role'].get('value') == 'loopback': + yield addr diff --git a/inventory.yml b/inventory.yml index 8fee281..0b952f4 100644 --- a/inventory.yml +++ b/inventory.yml @@ -13,3 +13,5 @@ query_filters: - role: 'compute-node' - role: 'storage-node' - role: 'server' +group_by: + - cluster diff --git a/roles/ceph/tasks/main.yml b/roles/ceph/tasks/main.yml index 085180b..fe0118b 100644 --- a/roles/ceph/tasks/main.yml +++ b/roles/ceph/tasks/main.yml @@ -1,17 +1,17 @@ +- name: Get all nodes in my cluster + set_fact: + nodes: "{{ groups['cluster_'+cluster] | map('extract', hostvars) }}" + - name: Configure /etc/hosts template: dest: /etc/hosts src: hosts.j2 -- name: Get cluster - set_fact: - cluster: "{{ query('netbox.netbox.nb_lookup', 'clusters', raw_data=true, api_filter='name='~cluster) | first }}" - - name: Generate my SSH key openssh_keypair: path: /root/.ssh/id_ed25519 type: ed25519 - comment: "root@{{ ansible_hostname }}" + comment: "root@{{ inventory_hostname }}" register: my_key - name: Deploy my key on other nodes @@ -20,7 +20,7 @@ key: "{{ my_key.public_key }}" comment: "{{ my_key.comment }}" delegate_to: "{{ item }}" - loop: "{{ query('netbox.netbox.nb_lookup', 'devices', api_filter='cluster_id='~cluster.id, raw_data=true) | map(attribute='name') }}" + loop: "{{ nodes | map(attribute='inventory_hostname') }}" - name: Install required packages package: diff --git a/roles/ceph/templates/hosts.j2 b/roles/ceph/templates/hosts.j2 index 9fdb26b..30f170b 100644 --- a/roles/ceph/templates/hosts.j2 +++ b/roles/ceph/templates/hosts.j2 @@ -3,9 +3,8 @@ ff02::1 ip6-allnodes ff02::2 ip6-allrouters -{% set my_cluster = query('netbox.netbox.nb_lookup', 'clusters', raw_data=true, api_filter='name='~cluster) | first %} -{% for host in query('netbox.netbox.nb_lookup', 'devices', raw_data=true, api_filter='cluster_id='~my_cluster.id) | map(attribute='name') %} -{% for address in (hostvars[host].interfaces | selectattr('name', 'equalto', 'lo') | map(attribute='ip_addresses') | first) %} -{{ address.address | ipaddr('address') }} {{ host }} +{% for node in nodes %} +{% for address in node|device_address %} +{{ address.address | ipaddr('address') }} {{ node.inventory_hostname }} {% endfor %} {% endfor %} diff --git a/roles/ceph/templates/nftables.conf.j2 b/roles/ceph/templates/nftables.conf.j2 index 31c3419..bf1da05 100644 --- a/roles/ceph/templates/nftables.conf.j2 +++ b/roles/ceph/templates/nftables.conf.j2 @@ -2,16 +2,28 @@ flush ruleset -# Just a temporary filter until we get our shit together policy-wise. table inet filter { - set allowed { - type ipv4_addr; flags interval - elements = { 10.32.0.0/14, 193.2.76.176/24, 192.168.19.0/24, 192.168.251.0/24, 88.200.23.0/24 } + set cluster { + type ipv4_addr; flags interval; auto-merge + elements = { +{{ nodes | map('device_address') | flatten | selectattr('family.value', '==', 4) | map(attribute='address') | join(',\n') | indent(12, first=True) }} + } + } + set cluster/6 { + type ipv6_addr; flags interval; auto-merge + elements = { +{{ nodes | map('device_address') | flatten | selectattr('family.value', '==', 6) | map(attribute='address') | join(',\n') | indent(12, first=True) }} + } } + # Just a temporary filter until we get our shit together policy-wise. + set allowed { + type ipv4_addr; flags interval + elements = { 10.32.0.0/14, 193.2.76.176/24, 192.168.251.0/24, 88.200.23.0/24 } + } set allowed/6 { type ipv6_addr; flags interval - elements = { 2001:1470:fffd::/48 } + elements = { 2001:1470:fffd:3432::/64, 2001:1470:fffd:a000::/64 } } chain input { @@ -24,6 +36,11 @@ table inet filter { iif lan0 ip6 saddr fe80::/64 accept iif lan1 ip6 saddr fe80::/64 accept + iif mgmt accept comment "management access" + + ip saddr @cluster accept comment "accept connections from other nodes" + ip6 saddr @cluster/6 accept comment "accept connections from other nodes" + ip saddr @allowed accept ip6 saddr @allowed/6 accept }