diff --git a/docs/dictionary/en-custom.txt b/docs/dictionary/en-custom.txt index 7c816e0703..e5f0a6332a 100644 --- a/docs/dictionary/en-custom.txt +++ b/docs/dictionary/en-custom.txt @@ -23,6 +23,7 @@ arxcruz AssignedTeam auth authfile +autoconfiguration autohold autoholds autoscale @@ -147,6 +148,7 @@ dfb dfce dfg dhcp +dhcpv dib dicts dirs @@ -480,9 +482,11 @@ qtjhbpzc quickstart rabbitmq radosgw +radvd raukadah rbd rdk +rdnss rdo rdoinfo rdoproject @@ -529,6 +533,7 @@ Sinha sizepercent skbg skiplist +slaac snr specificities spnego @@ -537,6 +542,7 @@ src sshkey ssl sso +stateful stderr stdout stp @@ -584,6 +590,7 @@ uidmap unclaim undefine undercloud +unicast unittest unmanaged uoyt diff --git a/roles/radvd/README.md b/roles/radvd/README.md new file mode 100644 index 0000000000..2a13198637 --- /dev/null +++ b/roles/radvd/README.md @@ -0,0 +1,179 @@ +# radvd + +Manage radvd (Router Advertisement Daemon) configuration. + +This role provides IPv6 Router Advertisements for network interfaces, enabling +Stateless Address Autoconfiguration (SLAAC) and/or DHCPv6. + +## Privilege escalation + +- Package installation +- Writing in protected locations `/etc/radvd.conf`, `/etc/cifmw-radvd.d` +- Managing system service `radvd.service` + +## Common Parameters + +* `cifmw_radvd_basedir`: (String) Configuration fragments directory. Defaults to `/etc/cifmw-radvd.d`. +* `cifmw_radvd_networks`: (List) List of networks to configure. Defaults to `[]`. +* `cifmw_radvd_remove_package`: (Bool) Remove the radvd package during cleanup. Defaults to `false`. + +## Network Configuration + +Each network in `cifmw_radvd_networks` supports the following parameters: + +* `name`: (String) Network/interface name. **Required**. +* `state`: (String) Network status. Must be either `present` or `absent`. Defaults to `present`. +* `prefixes`: (List[mapping]) List of IPv6 prefixes to advertise. **Required when state is present**. +* `adv_send_advert`: (Bool) Enable/disable router advertisements. Defaults to `true`. +* `adv_managed_flag`: (Bool) Managed address configuration flag (M-flag). Indicates DHCPv6 for addresses. +* `adv_other_config_flag`: (Bool) Other configuration flag (O-flag). Indicates DHCPv6 for other configuration. +* `adv_ra_solicited_unicast`: (Bool) Enable unicast router advertisements. +* `adv_link_mtu`: (Int) Advertised MTU for the link. +* `min_rtr_adv_interval`: (Int) Minimum router advertisement interval in seconds. +* `max_rtr_adv_interval`: (Int) Maximum router advertisement interval in seconds. +* `routes`: (List[mapping]) List of routes to advertise. Optional. +* `rdnss`: (List[mapping]) List of recursive DNS servers to advertise. Optional. + +### Prefix mapping + +* `network`: (String) IPv6 prefix (e.g., `2001:db8:1::/64`). **Required**. +* `adv_on_link`: (Bool) On-link flag. Defaults to `true`. +* `adv_autonomous`: (Bool) Autonomous address configuration flag (SLAAC). Defaults to `true`. +* `adv_router_addr`: (Bool) Include router address in prefix information. +* `adv_valid_lifetime`: (String/Int) Valid lifetime for the prefix (e.g., `86400`, `infinity`). +* `adv_preferred_lifetime`: (String/Int) Preferred lifetime for the prefix. + +### Route mapping + +* `network`: (String) IPv6 route prefix. **Required**. +* `adv_route_preference`: (String) Route preference (`low`, `medium`, `high`). +* `adv_route_lifetime`: (Int) Route lifetime in seconds. + +### RDNSS mapping + +* `servers`: (List[String]) List of IPv6 DNS server addresses. **Required**. +* `adv_rdnss_lifetime`: (Int) RDNSS lifetime in seconds. + +## Examples + +### Basic network with SLAAC only + +```yaml +- name: Configure radvd networks + vars: + cifmw_radvd_networks: + - name: testnet + adv_managed_flag: false + adv_other_config_flag: false + adv_link_mtu: 1500 + min_rtr_adv_interval: 30 + max_rtr_adv_interval: 100 + prefixes: + - network: "2001:db8:1::/64" + adv_on_link: true + adv_autonomous: true + adv_router_addr: true + ansible.builtin.include_role: + name: radvd +``` + +### Network with DHCPv6 for addresses and other configuration + +```yaml +- name: Configure radvd with DHCPv6 + vars: + cifmw_radvd_networks: + - name: provisioning + adv_managed_flag: true + adv_other_config_flag: true + adv_ra_solicited_unicast: true + adv_link_mtu: 1500 + min_rtr_adv_interval: 30 + max_rtr_adv_interval: 100 + prefixes: + - network: "2001:db8:2::/64" + adv_on_link: true + adv_autonomous: false + rdnss: + - servers: + - "2001:db8:2::53" + adv_rdnss_lifetime: 300 + ansible.builtin.include_role: + name: radvd +``` + +### Multiple networks + +```yaml +- name: Configure multiple networks + vars: + cifmw_radvd_networks: + - name: net1 + adv_managed_flag: true + adv_other_config_flag: true + adv_link_mtu: 1500 + min_rtr_adv_interval: 30 + max_rtr_adv_interval: 100 + prefixes: + - network: "2001:db8:1::/64" + adv_on_link: true + adv_autonomous: true + - name: net2 + adv_managed_flag: false + adv_other_config_flag: false + prefixes: + - network: "2001:db8:2::/64" + adv_on_link: true + adv_autonomous: true + ansible.builtin.include_role: + name: radvd +``` + +### Remove a network configuration + +```yaml +- name: Remove radvd configuration for a network + vars: + cifmw_radvd_networks: + - name: testnet + state: absent + ansible.builtin.include_role: + name: radvd +``` + +### Cleanup entire radvd service + +```yaml +- name: Cleanup radvd + vars: + # Set to true to also remove the radvd package (default: false) + cifmw_radvd_remove_package: false + ansible.builtin.include_role: + name: radvd + tasks_from: cleanup.yml +``` + +## Understanding the flags + +### Managed Flag (M-flag) - `adv_managed_flag` + +When set to `true`, hosts should use DHCPv6 to obtain IPv6 addresses (stateful DHCPv6). +When set to `false`, hosts should use SLAAC (Stateless Address Autoconfiguration) based on the advertised prefix. + +### Other Config Flag (O-flag) - `adv_other_config_flag` + +When set to `true`, hosts should use DHCPv6 to obtain other configuration information (DNS, NTP, etc.). + +### Common configurations + +1. **SLAAC only**: `adv_managed_flag: false`, `adv_other_config_flag: false`, `adv_autonomous: true` +2. **SLAAC + DHCPv6 for options**: `adv_managed_flag: false`, `adv_other_config_flag: true`, `adv_autonomous: true` +3. **DHCPv6 for everything**: `adv_managed_flag: true`, `adv_other_config_flag: true`, `adv_autonomous: false` + +## Notes + +- The interface/bridge specified by the `name` parameter must exist before radvd can advertise on it. +- IPv6 forwarding must be enabled on the host for router advertisements to work properly. +- Multiple prefixes can be advertised on the same interface. +- The role uses the system `radvd.service` from the RPM package. +- Configuration is assembled from fragments in `/etc/cifmw-radvd.d/` into `/etc/radvd.conf`. diff --git a/roles/radvd/defaults/main.yml b/roles/radvd/defaults/main.yml new file mode 100644 index 0000000000..1e644a7360 --- /dev/null +++ b/roles/radvd/defaults/main.yml @@ -0,0 +1,22 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +# All variables within this role should have a prefix of "cifmw_radvd" + +cifmw_radvd_basedir: "/etc/cifmw-radvd.d" +cifmw_radvd_networks: [] +cifmw_radvd_remove_package: false diff --git a/roles/radvd/handlers/main.yml b/roles/radvd/handlers/main.yml new file mode 100644 index 0000000000..bbaa821a98 --- /dev/null +++ b/roles/radvd/handlers/main.yml @@ -0,0 +1,21 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: Restart radvd service + become: true + ansible.builtin.systemd: + name: radvd.service + state: restarted diff --git a/roles/radvd/meta/main.yml b/roles/radvd/meta/main.yml new file mode 100644 index 0000000000..8fd358bb26 --- /dev/null +++ b/roles/radvd/meta/main.yml @@ -0,0 +1,30 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +galaxy_info: + author: CI Framework + description: CI Framework Role -- radvd + company: Red Hat + license: Apache-2.0 + min_ansible_version: "2.14" + namespace: cifmw + galaxy_tags: + - cifmw + +# List your role dependencies here, one per line. Be sure to remove the '[]' above, +# if you add dependencies to this list. +dependencies: [] diff --git a/roles/radvd/molecule/default/cleanup.yml b/roles/radvd/molecule/default/cleanup.yml new file mode 100644 index 0000000000..00eac85ed5 --- /dev/null +++ b/roles/radvd/molecule/default/cleanup.yml @@ -0,0 +1,52 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: Cleanup + hosts: all + tasks: + - name: Copy generated content in ci-framework-data/artifacts + vars: + dest_dir: >- + {{ + (ansible_user_dir, + 'ci-framework-data', + 'artifacts') | path_join + }} + ansible.posix.synchronize: + src: "{{ item }}" + dest: "{{ dest_dir }}" + loop: + - /etc/radvd.conf + - /etc/cifmw-radvd.d/ + + - name: Cleanup radvd + ansible.builtin.import_role: + name: "radvd" + tasks_from: "cleanup.yml" + + - name: Check if cleanup files still exist + become: true + ansible.builtin.stat: + path: "{{ item }}" + register: _cleanup_check + loop: + - /etc/radvd.conf + - /etc/cifmw-radvd.d + + - name: Assert cleanup was successful + ansible.builtin.assert: + that: + - not (_cleanup_check.results | map(attribute='stat.exists') | list | max) diff --git a/roles/radvd/molecule/default/converge.yml b/roles/radvd/molecule/default/converge.yml new file mode 100644 index 0000000000..b06d14bd8a --- /dev/null +++ b/roles/radvd/molecule/default/converge.yml @@ -0,0 +1,165 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +- name: Converge + hosts: all + vars: + cifmw_radvd_networks: + - name: testnet1 + adv_managed_flag: true + adv_other_config_flag: true + adv_ra_solicited_unicast: true + adv_link_mtu: 1500 + min_rtr_adv_interval: 30 + max_rtr_adv_interval: 100 + prefixes: + - network: "2001:db8:1::/64" + adv_on_link: true + adv_autonomous: true + adv_router_addr: true + - name: testnet2 + adv_managed_flag: true + adv_other_config_flag: true + adv_link_mtu: 1500 + min_rtr_adv_interval: 30 + max_rtr_adv_interval: 100 + prefixes: + - network: "2001:db8:2::/64" + adv_on_link: true + adv_autonomous: false + rdnss: + - servers: + - "2001:db8:2::53" + adv_rdnss_lifetime: 300 + - name: testnet3 + adv_managed_flag: false + adv_other_config_flag: false + adv_link_mtu: 9000 + min_rtr_adv_interval: 30 + max_rtr_adv_interval: 600 + prefixes: + - network: "2001:db8:3::/64" + adv_on_link: true + adv_autonomous: true + rdnss: + - servers: + - "2001:db8:3::53" + adv_rdnss_lifetime: 600 + roles: + - role: "radvd" + tasks: + - name: Verify radvd configuration is valid + become: true + ansible.builtin.command: + cmd: /usr/sbin/radvd -c -C /etc/radvd.conf + changed_when: false + + - name: Check if configuration files exist + become: true + ansible.builtin.stat: + path: "{{ item }}" + register: _config_files + loop: + - /etc/radvd.conf + - /etc/cifmw-radvd.d/testnet1.conf + - /etc/cifmw-radvd.d/testnet2.conf + - /etc/cifmw-radvd.d/testnet3.conf + + - name: Assert all configuration files exist + ansible.builtin.assert: + that: + - _config_files.results | map(attribute='stat.exists') | list | min + + - name: Verify testnet1 configuration content + become: true + ansible.builtin.slurp: + path: /etc/cifmw-radvd.d/testnet1.conf + register: _testnet1_conf + + - name: Check testnet1 configuration has expected content + vars: + _config: "{{ _testnet1_conf.content | b64decode }}" + ansible.builtin.assert: + that: + - "'interface testnet1' in _config" + - "'AdvSendAdvert on' in _config" + - "'AdvManagedFlag on' in _config" + - "'AdvOtherConfigFlag on' in _config" + - "'AdvRASolicitedUnicast on' in _config" + - "'AdvLinkMTU 1500' in _config" + - "'MinRtrAdvInterval 30' in _config" + - "'MaxRtrAdvInterval 100' in _config" + - "'prefix 2001:db8:1::/64' in _config" + - "'AdvOnLink on' in _config" + - "'AdvAutonomous on' in _config" + - "'AdvRouterAddr on' in _config" + + - name: Verify testnet2 configuration has RDNSS + become: true + ansible.builtin.slurp: + path: /etc/cifmw-radvd.d/testnet2.conf + register: _testnet2_conf + + - name: Check testnet2 configuration has RDNSS + vars: + _config: "{{ _testnet2_conf.content | b64decode }}" + ansible.builtin.assert: + that: + - "'RDNSS 2001:db8:2::53' in _config" + - "'AdvRDNSSLifetime 300' in _config" + - "'AdvAutonomous off' in _config" + + - name: Verify service is running + become: true + ansible.builtin.systemd: + name: radvd.service + register: _service_status + + - name: Assert service is active + ansible.builtin.assert: + that: + - _service_status.status.ActiveState == 'active' + + - name: Remove testnet3 network configuration + vars: + cifmw_radvd_networks: + - name: testnet3 + state: absent + ansible.builtin.include_role: + name: radvd + + - name: Verify testnet3 network configuration was removed + become: true + ansible.builtin.stat: + path: /etc/cifmw-radvd.d/testnet3.conf + register: _testnet3_conf + + - name: Assert testnet3 configuration is removed + ansible.builtin.assert: + that: + - not _testnet3_conf.stat.exists + + - name: Verify service is still running after network removal + become: true + ansible.builtin.systemd: + name: radvd.service + register: _service_status_after + + - name: Assert service is still active + ansible.builtin.assert: + that: + - _service_status_after.status.ActiveState == 'active' diff --git a/roles/radvd/molecule/default/molecule.yml b/roles/radvd/molecule/default/molecule.yml new file mode 100644 index 0000000000..fda947cafe --- /dev/null +++ b/roles/radvd/molecule/default/molecule.yml @@ -0,0 +1,11 @@ +--- +# Mainly used to override the defaults set in .config/molecule/ +# By default, it uses the "config_podman.yml" - in CI, it will use +# "config_local.yml". +log: true + +provisioner: + name: ansible + log: true + env: + ANSIBLE_STDOUT_CALLBACK: yaml diff --git a/roles/radvd/molecule/default/prepare.yml b/roles/radvd/molecule/default/prepare.yml new file mode 100644 index 0000000000..d922cb656a --- /dev/null +++ b/roles/radvd/molecule/default/prepare.yml @@ -0,0 +1,45 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +- name: Prepare + hosts: all + roles: + - role: test_deps + tasks: + - name: Create dummy interface for testnet1 network + become: true + community.general.nmcli: + type: dummy + conn_name: testnet1 + ip6: "2001:db8:1::1/64" + state: present + + - name: Create dummy interface for testnet2 network + become: true + community.general.nmcli: + type: dummy + conn_name: testnet2 + ip6: "2001:db8:2::1/64" + state: present + + - name: Create dummy interface for testnet3 network + become: true + community.general.nmcli: + type: dummy + conn_name: testnet3 + ip6: "2001:db8:3::1/64" + state: present diff --git a/roles/radvd/tasks/cleanup.yml b/roles/radvd/tasks/cleanup.yml new file mode 100644 index 0000000000..4e15287616 --- /dev/null +++ b/roles/radvd/tasks/cleanup.yml @@ -0,0 +1,42 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: Stop and disable radvd service + become: true + ansible.builtin.systemd: + name: radvd.service + enabled: false + state: stopped + +- name: Remove radvd configuration file + become: true + ansible.builtin.file: + path: "/etc/radvd.conf" + state: absent + +- name: Remove configuration directory + become: true + ansible.builtin.file: + path: "{{ cifmw_radvd_basedir }}" + state: absent + +- name: Remove radvd package + become: true + when: + - cifmw_radvd_remove_package | bool + ansible.builtin.package: + name: radvd + state: absent diff --git a/roles/radvd/tasks/configure.yml b/roles/radvd/tasks/configure.yml new file mode 100644 index 0000000000..a2b8cfb45b --- /dev/null +++ b/roles/radvd/tasks/configure.yml @@ -0,0 +1,34 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: Install radvd package + become: true + ansible.builtin.package: + name: radvd + state: present + +- name: Manage configuration directory + become: true + ansible.builtin.file: + mode: "0755" + path: "{{ cifmw_radvd_basedir }}" + state: directory + +- name: Enable radvd service + become: true + ansible.builtin.systemd: + name: radvd.service + enabled: true diff --git a/roles/radvd/tasks/main.yml b/roles/radvd/tasks/main.yml new file mode 100644 index 0000000000..2b9d528e0e --- /dev/null +++ b/roles/radvd/tasks/main.yml @@ -0,0 +1,32 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: Install and configure radvd + ansible.builtin.import_tasks: configure.yml + +- name: Manage radvd networks + when: + - cifmw_radvd_networks | length > 0 + ansible.builtin.include_tasks: manage_network.yml + loop: "{{ cifmw_radvd_networks }}" + loop_control: + loop_var: cifmw_radvd_network + +# Flush handlers to ensure the service is started before the role completes. +# This guarantees that radvd is running when control returns to the caller, +# so any subsequent tasks that depend on radvd will work correctly. +- name: Flush handlers to start/restart radvd service + ansible.builtin.meta: flush_handlers diff --git a/roles/radvd/tasks/manage_network.yml b/roles/radvd/tasks/manage_network.yml new file mode 100644 index 0000000000..2da8e828c1 --- /dev/null +++ b/roles/radvd/tasks/manage_network.yml @@ -0,0 +1,52 @@ +--- +# Copyright Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +- name: Assert mandatory parameters + ansible.builtin.assert: + that: + - cifmw_radvd_network.name is defined + - cifmw_radvd_network.state | default('present') in ['present', 'absent'] + - cifmw_radvd_network.state | default('present') == 'absent' or cifmw_radvd_network.prefixes is defined + - cifmw_radvd_network.state | default('present') == 'absent' or cifmw_radvd_network.prefixes | type_debug == "list" + +- name: Create network configuration fragment + become: true + when: + - cifmw_radvd_network.state | default('present') == 'present' + ansible.builtin.template: + dest: >- + {{ cifmw_radvd_basedir }}/{{ cifmw_radvd_network.name }}.conf + mode: "0644" + src: "network.conf.j2" + +- name: Remove network configuration fragment + become: true + when: + - cifmw_radvd_network.state | default('present') == 'absent' + ansible.builtin.file: + path: >- + {{ cifmw_radvd_basedir }}/{{ cifmw_radvd_network.name }}.conf + state: absent + +- name: Assemble radvd configuration from fragments + become: true + notify: Restart radvd service + ansible.builtin.assemble: + src: "{{ cifmw_radvd_basedir }}" + dest: "/etc/radvd.conf" + regexp: '\.conf$' + mode: "0644" + validate: "/usr/sbin/radvd -c -C %s" diff --git a/roles/radvd/templates/network.conf.j2 b/roles/radvd/templates/network.conf.j2 new file mode 100644 index 0000000000..d24aea65aa --- /dev/null +++ b/roles/radvd/templates/network.conf.j2 @@ -0,0 +1,63 @@ +# Managed by ci-framework/radvd +# Configuration for {{ cifmw_radvd_network.name }} network + +interface {{ cifmw_radvd_network.name }} +{ + AdvSendAdvert {{ (cifmw_radvd_network.adv_send_advert | default(true)) | ternary('on', 'off') }}; +{%- if cifmw_radvd_network.adv_managed_flag is defined %} + AdvManagedFlag {{ cifmw_radvd_network.adv_managed_flag | ternary('on', 'off') }}; +{%- endif %} +{%- if cifmw_radvd_network.adv_other_config_flag is defined %} + AdvOtherConfigFlag {{ cifmw_radvd_network.adv_other_config_flag | ternary('on', 'off') }}; +{%- endif %} +{%- if cifmw_radvd_network.adv_ra_solicited_unicast is defined %} + AdvRASolicitedUnicast {{ cifmw_radvd_network.adv_ra_solicited_unicast | ternary('on', 'off') }}; +{%- endif %} +{%- if cifmw_radvd_network.adv_link_mtu is defined %} + AdvLinkMTU {{ cifmw_radvd_network.adv_link_mtu }}; +{%- endif %} +{%- if cifmw_radvd_network.min_rtr_adv_interval is defined %} + MinRtrAdvInterval {{ cifmw_radvd_network.min_rtr_adv_interval }}; +{%- endif %} +{%- if cifmw_radvd_network.max_rtr_adv_interval is defined %} + MaxRtrAdvInterval {{ cifmw_radvd_network.max_rtr_adv_interval }}; +{%- endif %} +{%- for prefix in cifmw_radvd_network.prefixes | default([]) %} + prefix {{ prefix.network }} + { + AdvOnLink {{ (prefix.adv_on_link | default(true)) | ternary('on', 'off') }}; + AdvAutonomous {{ (prefix.adv_autonomous | default(true)) | ternary('on', 'off') }}; +{%- if prefix.adv_router_addr is defined %} + AdvRouterAddr {{ prefix.adv_router_addr | ternary('on', 'off') }}; +{%- endif %} +{%- if prefix.adv_valid_lifetime is defined %} + AdvValidLifetime {{ prefix.adv_valid_lifetime }}; +{%- endif %} +{%- if prefix.adv_preferred_lifetime is defined %} + AdvPreferredLifetime {{ prefix.adv_preferred_lifetime }}; +{%- endif %} + }; + +{%- endfor %} +{%- for route in cifmw_radvd_network.routes | default([]) %} + route {{ route.network }} + { +{%- if route.adv_route_preference is defined %} + AdvRoutePreference {{ route.adv_route_preference }}; +{%- endif %} +{%- if route.adv_route_lifetime is defined %} + AdvRouteLifetime {{ route.adv_route_lifetime }}; +{%- endif %} + }; + +{%- endfor %} +{%- for rdnss in cifmw_radvd_network.rdnss | default([]) %} + RDNSS {{ rdnss.servers | join(' ') }} + { +{%- if rdnss.adv_rdnss_lifetime is defined %} + AdvRDNSSLifetime {{ rdnss.adv_rdnss_lifetime }}; +{%- endif %} + }; + +{%- endfor %} +}; diff --git a/zuul.d/molecule.yaml b/zuul.d/molecule.yaml index e1d4e77efc..b29426eb15 100644 --- a/zuul.d/molecule.yaml +++ b/zuul.d/molecule.yaml @@ -661,6 +661,17 @@ parent: cifmw-molecule-base vars: TEST_RUN: podman +- job: + files: + - ^common-requirements.txt + - ^test-requirements.txt + - ^roles/radvd/.* + - ^ci/playbooks/molecule.* + - ^.config/molecule/.* + name: cifmw-molecule-radvd + parent: cifmw-molecule-base + vars: + TEST_RUN: radvd - job: files: - ^common-requirements.txt diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml index 8ca3c251c6..8def5eb491 100644 --- a/zuul.d/projects.yaml +++ b/zuul.d/projects.yaml @@ -86,6 +86,7 @@ - cifmw-molecule-pkg_build - cifmw-molecule-podman - cifmw-molecule-polarion + - cifmw-molecule-radvd - cifmw-molecule-recognize_ssh_keypair - cifmw-molecule-registry_deploy - cifmw-molecule-repo_setup