Skip to content

Commit

Permalink
Role: network :: consolidation phase #1
Browse files Browse the repository at this point in the history
  • Loading branch information
aybarsm committed Jul 13, 2024
1 parent 2209d1b commit 5ef6f88
Show file tree
Hide file tree
Showing 15 changed files with 428 additions and 2 deletions.
12 changes: 12 additions & 0 deletions roles/ansible/vars/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ __ansible__config:
apt_key:
uniques: ['keyserver', 'url', 'id', 'file' ,'data']
aliases: {}
find:
required: ['paths']
aliases:
excludes: ['exclude']
paths: ['name', 'path']
patterns: ['pattern']
posix:
sysctl:
required: ['name', 'value']
aliases:
name: ['key']
value: ['val']
community:
general:
sudoers:
Expand Down
2 changes: 1 addition & 1 deletion roles/auth/tasks/ssh.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
# TODO: Renew SSH host keys only once
- name: Apply ssh daemon configuration
become: true
ansible.builtin.template:
Expand Down Expand Up @@ -42,4 +43,3 @@
when:
- auth__ssh_changes_strategy.module is defined
- auth__ssh_changes_strategy.immediate | default(false) | bool

83 changes: 83 additions & 0 deletions roles/network/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
network__role_enabled: false

network__manage_systemd: false
network__manage_interfaces: false
network__manage_sysctl: false
network__manage_hosts: false

network__default: []
network__group: []
network__host: []

##### BEGIN: network systemd vars
# Ensures system manager is systemd - ansible_service_mgr == "systemd"
network__systemd_ensure_service_manager: true
network__systemd_apply_changes: false
network__systemd_backup: true
network__systemd_cleanup: false
network__systemd_cleanup_use_regex: true
# Naming scheme to be used with aybarsm.linux.grub role to avoid kernel naming conflicts
# i.e. grub cmdline :: net.naming-scheme=v252
# Consult: https://manpages.debian.org/bookworm/systemd/systemd.net-naming-scheme.7.en.html
network__systemd_naming_scheme: "v252"
network__systemd_dir: /etc/systemd/network
network__systemd_template: etc/systemd/network/unit.j2
network__systemd_change_strategy:
# Available modules: systemd_service
# Set module other than available options to disable applying changes
module: systemd_service
# immediate can be true or false (Flushes the handlers immediately)
immediate: false
# Use name for service or systemd_service module
name: 'systemd-networkd.service'
state: reloaded
##### END: network systemd vars

##### BEGIN: network interfaces vars
network__interfaces_file: /etc/network/interfaces
# Keep the loopback interface in the file
network__interfaces_keep_lo: true
# The location of the source line in the file (controversial topic)
network__interfaces_source_position: bottom
network__interfaces_source_line: "source /etc/network/interfaces.d/*"

network__interfaces_backup: true
network__interfaces_template: etc/network/interfaces.j2

# iface XXX inet {manual|static|dhcp}
# Manual method only INCLUDES selected options whereas static and dhcp methods EXCLUDES selected options
network__interfaces_manual_includes: []
network__interfaces_static_excludes: []
network__interfaces_dhcp_excludes: [
'address', 'netmask', 'gateway', 'broadcast', 'network', 'dns-nameservers', 'dns-search',
'dns-domain', 'dns-domain-search', 'dns-options', 'dns-sortlist', 'dns-opts']

network__interfaces_change_strategy:
# Available modules: service, systemd_service, or command
# Set module other than available options to disable applying changes
module: service
# immediate can be true or false (Flushes the handlers immediately)
immediate: false
# Use name for service or systemd_service module
name: 'networking.service'
# Use cmd for command module
# cmd: ifreload -a
state: restarted
##### END: network interfaces vars

##### BEGIN: network sysctl vars
# No specific configuration is required for sysctl
##### END: network sysctl vars

##### BEGIN: network hosts vars
network__hosts_file: /etc/hosts
network__hosts_template: etc/hosts.j2
network__hosts_backup: true

# If enabled, the ansible inventory will be collected automatically
# and will be appended to the list of hosts, when ansible_host (ip address) is defined.
# ip: ansible_host, hostname: inventory_hostname_short, fqdn: inventory_hostname
network__hosts_auto_discovery: false
# Consult https://docs.ansible.com/ansible/latest/inventory_guide/intro_patterns.html for more information
network__hosts_auto_discovery_inventories: 'webservers:&atlanta'
##### END: network hosts vars
76 changes: 76 additions & 0 deletions roles/network/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
- name: Apply network interfaces changes via systemd service module
become: true
ansible.builtin.systemd_service:
daemon_reexec: "{{ service.daemon_reexec | default(omit) | bool }}"
daemon_reload: "{{ service.daemon_reload | default(omit) | bool }}"
enabled: "{{ service.enabled | default(omit) | bool }}"
force: "{{ service.force | default(omit) | bool }}"
masked: "{{ service.masked | default(omit) | bool }}"
name: "{{ service.name }}"
no_block : "{{ service.no_block | default(omit) | bool }}"
scope: "{{ service.scope | default(omit) }}"
state: "{{ service.state | default(omit) }}"
vars:
service: "{{ network__interfaces_change_strategy | aybarsm.helper.replace_aliases(__ansible__config.modules.ansible.builtin.systemd_service.aliases) }}"
register: network__interfaces_apply_changes_systemd_service
listen: "network__interfaces_apply_changes"
when:
- network__interfaces_change_strategy.module is defined
- network__interfaces_change_strategy.module == 'systemd_service'

- name: Apply network interfaces changes via service module
become: true
ansible.builtin.service:
arguments: "{{ service.arguments | default(omit) }}"
enabled: "{{ service.enabled | default(omit) }}"
name: "{{ service.name }}"
pattern: "{{ service.pattern | default(omit) }}"
runlevel: "{{ service.runlevel | default(omit) }}"
sleep: "{{ service.sleep | default(omit) }}"
state: "{{ service.state | default(omit) }}"
use: "{{ service.use | default(omit) }}"
vars:
service: "{{ network__interfaces_change_strategy | aybarsm.helper.replace_aliases(__ansible__config.modules.ansible.builtin.service.aliases) }}"
register: network__interfaces_apply_changes_service
listen: "network__interfaces_apply_changes"
when:
- network__interfaces_change_strategy.module is defined
- network__interfaces_change_strategy.module == 'service'

- name: Apply network interfaces changes via command module
become: true
ansible.builtin.command:
chdir: "{{ network__interfaces_change_strategy.chdir | default(omit) }}"
cmd: "{{ network__interfaces_change_strategy.cmd }}"
creates: "{{ network__interfaces_change_strategy.creates | default(omit) }}"
removes: "{{ network__interfaces_change_strategy.removes | default(omit) }}"
stdin: "{{ network__interfaces_change_strategy.stdin | default(omit) }}"
stdin_add_newline: "{{ network__interfaces_change_strategy.stdin_add_newline | default(omit) }}"
strip_empty_ends: "{{ network__interfaces_change_strategy.strip_empty_ends | default(omit) }}"
changed_when: true
register: network__interfaces_apply_changes_command
listen: "network__interfaces_apply_changes"
when:
- network__interfaces_change_strategy.module is defined
- network__interfaces_change_strategy.module == 'command'

- name: Apply systemd network changes via systemd service module
become: true
ansible.builtin.systemd_service:
daemon_reexec: "{{ service.daemon_reexec | default(omit) | bool }}"
daemon_reload: "{{ service.daemon_reload | default(omit) | bool }}"
enabled: "{{ service.enabled | default(omit) | bool }}"
force: "{{ service.force | default(omit) | bool }}"
masked: "{{ service.masked | default(omit) | bool }}"
name: "{{ service.name }}"
no_block : "{{ service.no_block | default(omit) | bool }}"
scope: "{{ service.scope | default(omit) }}"
state: "{{ service.state | default(omit) }}"
vars:
service: "{{ network__systemd_change_strategy | aybarsm.helper.replace_aliases(__ansible__config.modules.ansible.builtin.systemd_service.aliases) }}"
register: network__systemd_apply_changes_systemd_service
listen: "network__systemd_apply_changes"
when:
- network__systemd_change_strategy.module is defined
- network__systemd_change_strategy.module == 'systemd_service'
Empty file added roles/network/meta/main.yml
Empty file.
9 changes: 9 additions & 0 deletions roles/network/tasks/hosts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
- name: Deploy network hosts file configuration
become: true
ansible.builtin.template:
src: "{{ network__hosts_template }}"
dest: "{{ network__hosts_file }}"
backup: "{{ network__hosts_backup | default(omit) | bool }}"
when: (network__hosts_all_ipv4 | default([]) | length > 0) or (network__hosts_all_ipv6 | default([]) | length > 0)
register: network__hosts_deploy
20 changes: 20 additions & 0 deletions roles/network/tasks/interfaces.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
- name: Deploy network interfaces file configuration
become: true
ansible.builtin.template:
src: "{{ network__interfaces_template }}"
dest: "{{ network__interfaces_file }}"
backup: "{{ network__interfaces_backup | default(omit) | bool }}"
mode: "0644"
when:
- network__interfaces_all | type_debug == 'list'
- network__interfaces_all | length > 0
register: network__interfaces_deploy
notify: "network__interfaces_apply_changes"

- name: Apply network interfaces file changes
ansible.builtin.meta: 'flush_handlers'
when:
- network__interfaces_change_strategy.module is defined
- network__interfaces_change_strategy.module in __network_interfaces_available_change_modules
- network__interfaces_change_strategy.immediate | default(false) | bool
32 changes: 32 additions & 0 deletions roles/network/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
# Required for configuration management
- name: Load aybarsm ansible role main variables
ansible.builtin.include_vars: ../ansible/vars/main.yml

- name: Include systemd network tasks
ansible.builtin.include_tasks:
file: systemd.yml
when:
- network__role_enabled | default(false) | bool
- network__manage_systemd | default(false) | bool

- name: Include interfaces tasks
ansible.builtin.include_tasks:
file: interfaces.yml
when:
- network__role_enabled | default(false) | bool
- network__manage_interfaces | default(false) | bool

- name: Include posix sysctl tasks
ansible.builtin.include_tasks:
file: sysctl.yml
when:
- network__role_enabled | default(false) | bool
- network__manage_sysctl | default(false) | bool

- name: Include hosts tasks
ansible.builtin.include_tasks:
file: hosts.yml
when:
- network__role_enabled | default(false) | bool
- network__manage_hosts | default(false) | bool
16 changes: 16 additions & 0 deletions roles/network/tasks/sysctl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
- name: Deploy posix sysctl configuration
become: true
ansible.posix.sysctl:
name: "{{ item.name }}"
value: "{{ item.value }}"
ignoreerrors: "{{ item.ignoreerrors | default(omit) | bool }}"
reload: "{{ item.reload | default(omit) | bool }}"
state: "{{ item.state | default(omit) }}"
sysctl_file: "{{ item.sysctl_file | default(omit) }}"
sysctl_set: "{{ item.sysctl_set | default(omit) | bool }}"
loop: "{{ network__sysctl_all }}"
register: network__sysctl_deploy
when:
- network__sysctl_all | type_debug == 'list'
- network__sysctl_all | length > 0
42 changes: 42 additions & 0 deletions roles/network/tasks/systemd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
- name: Find unexpected systemd-network unit files
become: true
ansible.builtin.find:
paths: "{{ network__systemd_dir }}"
patterns: "{{ network__systemd_cleanup_patterns | default(omit) }}"
use_regex: "{{ network__systemd_cleanup_use_regex | default(omit) | bool }}"
register: network__systemd_find_cleanup_files
when: network__systemd_cleanup | default(false) | bool

- name: Remove unexpected systemd-network unit files
become: true
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop: "{{ network__systemd_find_cleanup_files.files | map(attribute='path') }}"
register: systemd__network_cleanup_files
notify: network__systemd_apply_changes
when:
- network__systemd_cleanup | default(false) | bool
- network__systemd_find_cleanup_files.files | length > 0

- name: Deploy systemd-network unit files
become: true
ansible.builtin.template:
src: "{{ network__systemd_template }}"
dest: "{{ network__systemd_dir }}/{{ item.name }}"
backup: "{{ network__systemd_backup | default(omit) | bool }}"
mode: "0644"
loop: "{{ network__systemd_all }}"
register: systemd__network_deploy
notify: network__systemd_apply_changes
when:
- network__systemd_all | type_debug == 'list'
- network__systemd_all | length > 0

- name: Apply network systemd changes
ansible.builtin.meta: 'flush_handlers'
when:
- network__systemd_change_strategy.moduele is defined
- network__systemd_change_strategy.module in __network_systemd_available_change_modules
- network__systemd_change_strategy.immediate | default(false) | bool
15 changes: 15 additions & 0 deletions roles/network/templates/etc/hosts.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
127.0.0.1 localhost.localdomain localhost
{% for ipv4_host in network__hosts_all_ipv4 %}
{{ ipv4_host.ip }} {{ ipv4_host.fqdn }} {{ ipv4_host.hostname }}
{% endfor %}

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
{% for ipv6_host in network__hosts_all_ipv6 %}
{{ ipv6_host.ip }} {{ ipv6_host.fqdn }} {{ ipv6_host.hostname }}
{% endfor %}
48 changes: 48 additions & 0 deletions roles/network/templates/etc/network/interfaces.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{{ ansible_managed | comment }}

{% if network__interfaces_source_position == 'top' %}
{{ network__interfaces_source_line }}

{% endif %}
{% if network__interfaces_keep_lo | bool %}
# The loopback network interface
auto lo
iface lo inet loopback
{% endif %}

{% for iface in network__interfaces_all %}
{% if 'mount' in iface and iface.mount != 'None' %}
{{ iface.mount }} {{ iface.name }}
{% endif %}
{% for addr_family in ['inet', 'inet6'] %}
{% if addr_family in iface %}
{% set ifaceMethod = iface[addr_family] | selectattr('name', 'equalto', 'method') | map(attribute='value') | first | default('') %}
{% if ifaceMethod in ['static', 'dhcp', 'manual'] %}
{% set ifaceParamsExclude = ['method'] %}
{% set ifaceParamsInclude = [] %}
{% if ifaceMethod == 'static' %}
{% set ifaceParamsExclude = ifaceParamsExclude + (network__interfaces_static_excludes | default([])) %}
{% elif ifaceMethod == 'dhcp' %}
{% set ifaceParamsExclude = ifaceParamsExclude + (network__interfaces_dhcp_excludes | default([])) %}
{% elif ifaceMethod == 'manual' %}
{% set ifaceParamsInclude = ifaceParamsInclude + (network__interfaces_manual_includes | default([])) %}
{% endif %}
{% set ifaceParams = iface[addr_family] %}
{% if ifaceParamsInclude | length > 0 %}
{% set ifaceParams = ifaceParams | selectattr('name', 'in', ifaceParamsInclude) %}
{% endif %}
{% if ifaceParamsExclude | length > 0 %}
{% set ifaceParams = ifaceParams | rejectattr('name', 'in', ifaceParamsExclude) %}
{% endif %}
iface {{ iface.name }} {{ addr_family }} {{ ifaceMethod }}
{% if ifaceParams | length > 0 %}
{{ ifaceParams | aybarsm.helper.to_querystring('name', 'value', ' ', '\n') | indent(4, true) }}
{% endif %}
{% endif %}

{% endif %}
{% endfor %}
{% endfor %}
{% if network__interfaces_source_position != 'top' %}
{{ network__interfaces_source_line }}
{% endif %}
8 changes: 8 additions & 0 deletions roles/network/templates/etc/systemd/network/unit.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{{ ansible_managed | comment }}

{% for section in item.children %}
{% set sectionName = ('[' if (section.name | first) != '[' else '') + (section.name | title) + (']' if (section.name | last) != ']' else '') %}
{{ sectionName }}
{{ section.children | aybarsm.helper.to_querystring('name', 'value', '=', '\n') }}

{% endfor %}
Loading

0 comments on commit 5ef6f88

Please sign in to comment.