Vendor Galaxy Roles and Collections
Some checks failed
/ Ansible Lint (push) Failing after 5m45s
/ Ansible Lint (pull_request) Failing after 4m59s

This commit is contained in:
Stefan Bethke 2026-02-06 22:07:16 +01:00
commit 2aed20393f
3553 changed files with 387444 additions and 2 deletions

View file

@ -0,0 +1,19 @@
dropbear_initramfs - Setup the dropbear ssh server in initramfs
Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
Copyright (C) 2017 DebOps <https://debops.org/>
SPDX-License-Identifier: GPL-3.0-only
This Ansible role is part of DebOps.
DebOps is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3, as
published by the Free Software Foundation.
DebOps is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DebOps. If not, see https://www.gnu.org/licenses/.

View file

@ -0,0 +1,281 @@
---
# .. vim: foldmarker=[[[,]]]:foldmethod=marker
# .. Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
# .. Copyright (C) 2017-2022 DebOps <https://debops.org/>
# .. SPDX-License-Identifier: GPL-3.0-only
# .. _dropbear_initramfs__ref_defaults:
# .. contents:: Sections
# :local:
#
# .. include:: ../../../../includes/global.rst
# Packages and installation [[[
# -----------------------------
# .. envvar:: dropbear_initramfs__base_packages [[[
#
# List of APT packages to install for :command:`dropbear_initramfs` support.
#
# Supported versions:
#
# * ``dropbear-initramfs``
# * ``dropbear``
#
dropbear_initramfs__base_packages:
- '{{ "dropbear"
if (ansible_distribution == "Ubuntu" and ansible_distribution_release in ["trusty"])
else "dropbear-initramfs" }}'
# ]]]
# .. envvar:: dropbear_initramfs__packages [[[
#
# List of additional APT packages to install during :command:`dropbear_initramfs`
# configuration.
dropbear_initramfs__packages: []
# ]]]
# .. envvar:: dropbear_initramfs__config_path [[[
#
# Path to dropbear initramfs configuration files.
dropbear_initramfs__config_path: '{{ "/etc/dropbear-initramfs"
if (ansible_distribution_release in ["stretch", "buster", "bullseye"])
else "/etc/dropbear/initramfs" }}'
# ]]]
# .. envvar:: dropbear_initramfs__config_file [[[
#
# Path to dropbear initramfs configuration file.
dropbear_initramfs__config_file: '{{ dropbear_initramfs__config_path + "/"
+ ("config"
if (ansible_distribution_release in ["stretch", "buster", "bullseye"])
else "dropbear.conf") }}'
# ]]]
# .. envvar:: dropbear_initramfs__deploy_state [[[
#
# What is the desired state which this role should achieve? Possible options:
#
# ``present``
# Default. Ensure that dropbear is configured in the initramfs to allow
# ssh connections.
#
# ``absent``
# Ensure that dropbear and related configuration maintained by this role are
# absent.
#
dropbear_initramfs__deploy_state: 'present'
# ]]]
# ]]]
# Simple initramfs network [[[
# ----------------------------
# Refer to https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt
# for support configuration options.
#
# Note that the ``IP`` kernel parameter only supports legacy IPv4. But dont
# worry, the role has you covered. Refer to
# :envvar:`dropbear_initramfs__interfaces`.
# .. envvar:: dropbear_initramfs__network_autoconf [[[
#
# Method to use for autoconfiguration. Use ``off`` or ``none`` for manual
# network configuration (see below).
dropbear_initramfs__network_autoconf: 'dhcp'
# ]]]
# .. envvar:: dropbear_initramfs__network_device [[[
#
# Default network device.
dropbear_initramfs__network_device: '{{ ansible_default_ipv6.interface
if ansible_default_ipv6.interface | d()
else (ansible_default_ipv4.interface
if ansible_default_ipv4.interface | d()
else "eth0") }}'
# ]]]
# .. envvar:: dropbear_initramfs__network_address [[[
#
# Manual network address to set.
dropbear_initramfs__network_address: '{{ ansible_default_ipv4.address }}'
# ]]]
# .. envvar:: dropbear_initramfs__network_netmask [[[
#
# Manual subnet mask to set.
dropbear_initramfs__network_netmask: '{{ ansible_default_ipv4.netmask }}'
# ]]]
# .. envvar:: dropbear_initramfs__network_gateway [[[
#
# Manual gateway to set.
dropbear_initramfs__network_gateway: '{{ ansible_default_ipv4.gateway }}'
# ]]]
# .. envvar:: dropbear_initramfs__network_manual [[[
#
# The ``IP`` kernel parameter used when
# :envvar:`dropbear_initramfs__network_autoconf` is disabled.
#
# The `ipwrap` filter causes IPv6 address to work on some platforms.
# Refer to: https://serverfault.com/questions/445296/is-there-a-linux-kernel-boot-parameter-to-configure-an-ipv6-address/701451#701451
dropbear_initramfs__network_manual: '{{
(dropbear_initramfs__network_address | ansible.utils.ipwrap) + "::" +
(dropbear_initramfs__network_gateway | ansible.utils.ipwrap) + ":" +
dropbear_initramfs__network_netmask + "::" +
dropbear_initramfs__network_device + ":none" }}'
# ]]]
# .. envvar:: dropbear_initramfs__network [[[
#
# The ``IP`` kernel parameter as it is configured by the role.
dropbear_initramfs__network: '{{ dropbear_initramfs__network_manual
if (dropbear_initramfs__network_autoconf in ["off", "none"])
else dropbear_initramfs__network_autoconf }}'
# ]]]
# ]]]
# Complex initramfs network [[[
# -----------------------------
# These variables are dictionaries with additional network configuration.
# See :ref:`dropbear_initramfs__ref_interfaces` documentation for more details.
# .. envvar:: dropbear_initramfs__interfaces [[[
#
# Dictionary which holds the configuration of additional network configuration
# for all hosts in the Ansible inventory.
dropbear_initramfs__interfaces: {}
# ]]]
# .. envvar:: dropbear_initramfs__group_interfaces [[[
#
# Dictionary which holds the configuration of additional network configuration
# for hosts in a specific Ansible inventory group.
dropbear_initramfs__group_interfaces: {}
# ]]]
# .. envvar:: dropbear_initramfs__host_interfaces [[[
#
# Dictionary which holds the configuration of additional network configuration
# for specific hosts in the Ansible inventory.
dropbear_initramfs__host_interfaces: {}
# ]]]
# .. envvar:: dropbear_initramfs__combined_interfaces [[[
#
# Dictionary which combines all of the other network interface
# configuration variables and is used in the role tasks and templates to
# generate the configuration.
dropbear_initramfs__combined_interfaces: '{{ lookup("template", "lookup/dropbear_initramfs__combined_interfaces.j2", convert_data=False) | from_yaml }}'
# ]]]
# ]]]
# Initramfs generation [[[
# ------------------------
# .. envvar:: dropbear_initramfs__update_options [[[
#
# Additional options for the :command:`update-initramfs` command.
# The default is to regenerate the initramfs for all installed kernel versions.
dropbear_initramfs__update_options: '-k all'
# ]]]
# ]]]
# Dropbear options [[[
# -------------------
# .. envvar:: dropbear_initramfs__port [[[
#
# The port dropbear listens on.
dropbear_initramfs__port: '22'
# ]]]
# .. envvar:: dropbear_initramfs__disable_password_login [[[
#
# Disable password login?
dropbear_initramfs__disable_password_login: '{{
True
if dropbear_initramfs__combined_authorized_keys | d()
else False
}}'
# ]]]
# .. envvar:: dropbear_initramfs__disable_port_forwarding [[[
#
# Disable local and remote port forwarding?
dropbear_initramfs__disable_port_forwarding: True
# ]]]
# .. envvar:: dropbear_initramfs__idle_timeout [[[
#
# Count of seconds after that dropbear times out.
dropbear_initramfs__idle_timeout: '180'
# ]]]
# .. envvar:: dropbear_initramfs__max_authentication_attempts [[[
#
# The maximum number of authentication attempts per connection.
dropbear_initramfs__max_authentication_attempts: '10'
# ]]]
# .. envvar:: dropbear_initramfs__forced_command [[[
#
# Override the command provided by the user and always run this command.
dropbear_initramfs__forced_command: ''
# ]]]
# .. envvar:: dropbear_initramfs__dropbear_options [[[
#
# Set options parsed to dropbear.
dropbear_initramfs__dropbear_options: '{{
"-p " + dropbear_initramfs__port +
(" -g -s" if dropbear_initramfs__disable_password_login | d() else "") +
(" -j -k" if dropbear_initramfs__disable_port_forwarding | d() else "") +
" -I " + dropbear_initramfs__idle_timeout +
" -T " + dropbear_initramfs__max_authentication_attempts +
(" -c " + dropbear_initramfs__forced_command if dropbear_initramfs__forced_command | d() else "")
}}'
# ]]]
# ]]]
# Authorized ssh keys [[[
# -----------------------
# See :ref:`dropbear_initramfs__ref_authorized_keys` for more details.
# .. envvar:: dropbear_initramfs__authorized_keys [[[
#
# List of authorized ssh keys configured on all hosts in the Ansible inventory.
dropbear_initramfs__authorized_keys: []
# ]]]
# .. envvar:: dropbear_initramfs__group_authorized_keys [[[
#
# List of authorized ssh keys configured on a group of hosts in the Ansible inventory.
dropbear_initramfs__group_authorized_keys: []
# ]]]
# .. envvar:: dropbear_initramfs__host_authorized_keys [[[
#
# List of authorized ssh keys configured on specific hosts in the Ansible inventory.
dropbear_initramfs__host_authorized_keys: []
# ]]]
# .. envvar:: dropbear_initramfs__combined_authorized_keys [[[
#
# Combines list of authorized ssh keys as used in the role tasks.
dropbear_initramfs__combined_authorized_keys: '{{ dropbear_initramfs__authorized_keys +
dropbear_initramfs__group_authorized_keys +
dropbear_initramfs__host_authorized_keys }}'
# ]]]
# .. envvar:: dropbear_initramfs__authorized_keys_key_options [[[
#
# List of default SSH options added to all public keys. If it's set to
# ``{{ omit }}``, no options will be added automatically. The list of options can be
# overridden by the ``item.options`` parameter.
# Refer to :manpage:`dropbear(8)` for details.
dropbear_initramfs__authorized_keys_key_options: '{{ omit }}'
# ]]]
# ]]]
# ]]]

View file

@ -0,0 +1,9 @@
---
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
# Copyright (C) 2017 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
- name: Update initramfs
ansible.builtin.command: update-initramfs -u {{ dropbear_initramfs__update_options }}
register: dropbear_initramfs__register_update
changed_when: dropbear_initramfs__register_update.changed | bool

View file

@ -0,0 +1,38 @@
---
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
# Copyright (C) 2017-2022 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
# Ensure that custom Ansible plugins and modules included in the main DebOps
# collection are available to roles in other collections.
collections: [ 'debops.debops' ]
dependencies: []
galaxy_info:
author: 'Robin Schneider'
description: 'Setup the dropbear ssh server in initramfs'
company: 'DebOps'
license: 'GPL-3.0-only'
min_ansible_version: '2.1.4'
platforms:
- name: 'Ubuntu'
versions: [ 'all' ]
- name: 'Debian'
versions: [ 'all' ]
galaxy_tags:
- system
- startup
- boot
- fde
- headless
- encryption
- security
- initramfs
- ssh
- cryptsetup

View file

@ -0,0 +1,82 @@
---
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
# Copyright (C) 2017 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
- name: Ensure specified packages are in there desired state
ansible.builtin.package:
name: '{{ q("flattened", (dropbear_initramfs__base_packages
+ dropbear_initramfs__packages)) }}'
state: '{{ "present" if (dropbear_initramfs__deploy_state == "present") else "absent" }}'
register: dropbear_initramfs__register_packages
until: dropbear_initramfs__register_packages is succeeded
tags: [ 'role::dropbear_initramfs:pkgs' ]
- name: Configure network in initramfs using kernel command line
ansible.builtin.template:
src: 'etc/initramfs-tools/conf.d/role.conf.j2'
dest: '/etc/initramfs-tools/conf.d/50_debops.dropbear_initramfs.conf'
mode: '0644'
when: (dropbear_initramfs__deploy_state == "present")
notify: [ 'Update initramfs' ]
- name: Configure dropbear options
ansible.builtin.template:
src: 'etc/dropbear/initramfs/dropbear.conf.j2'
dest: '{{ dropbear_initramfs__config_file }}'
mode: '0644'
when: (dropbear_initramfs__deploy_state == "present")
notify: [ 'Update initramfs' ]
- name: Configure to bring up additional interfaces/addresses in initramfs
ansible.builtin.template:
src: 'etc/initramfs-tools/scripts/local-top/debops_dropbear_initramfs.j2'
dest: '/etc/initramfs-tools/scripts/local-top/debops_dropbear_initramfs'
mode: '0755'
when: (dropbear_initramfs__deploy_state == "present")
notify: [ 'Update initramfs' ]
- name: Configure to bring down additional interfaces/addresses in initramfs
ansible.builtin.template:
src: 'etc/initramfs-tools/scripts/local-bottom/debops_dropbear_initramfs.j2'
dest: '/etc/initramfs-tools/scripts/local-bottom/debops_dropbear_initramfs'
mode: '0755'
when: (dropbear_initramfs__deploy_state == "present")
notify: [ 'Update initramfs' ]
- name: Configure authorized ssh keys
ansible.posix.authorized_key:
key: "{{ (item.key
if item.key is string
else (item.key | unique | join('\n') | string))
if item.key | d() else '' }}"
user: '{{ item.user | d("root") }}'
path: '{{ "/etc/initramfs-tools/root/.ssh/authorized_keys"
if ("dropbear" in dropbear_initramfs__base_packages)
else dropbear_initramfs__config_path + "/authorized_keys" }}'
key_options: '{{ (item.key_options if item.key_options is string else item.key_options | join(","))
if item.key_options is defined
else ((dropbear_initramfs__authorized_keys_key_options
if dropbear_initramfs__authorized_keys_key_options is string
else dropbear_initramfs__authorized_keys_key_options | join(","))
if dropbear_initramfs__authorized_keys_key_options != omit else "")
}}'
state: '{{ (item.state | d("present")) if (dropbear_initramfs__deploy_state == "present") else "absent" }}'
exclusive: '{{ item.exclusive | d(omit) }}'
comment: '{{ item.comment | d(omit) }}'
manage_dir: False
notify: [ 'Update initramfs' ]
loop: '{{ q("flattened", dropbear_initramfs__combined_authorized_keys) }}'
loop_control:
label: '{{ {"key": item.key} }}'
- name: Remove files in deploy state absent
ansible.builtin.file:
path: '{{ item }}'
state: 'absent'
when: (dropbear_initramfs__deploy_state == 'absent')
notify: [ 'Update initramfs' ]
with_items:
- '/etc/initramfs-tools/conf.d/50_debops.dropbear_initramfs.conf'
- '/etc/initramfs-tools/scripts/local-top/debops_dropbear_initramfs'
- '/etc/initramfs-tools/scripts/local-bottom/debops_dropbear_initramfs'

View file

@ -0,0 +1,39 @@
{# Copyright (C) 2015-2017,2024 Robin Schneider <ypid@riseup.net>
# Copyright (C) 2017 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
#}
# {{ ansible_managed }}
#
# Configuration options for the dropbear-initramfs boot scripts.
# Variable assignment follow shell semantics and escaping/quoting rules.
# You must run update-initramfs(8) to effect changes to this file (like
# for other files in the '{{ dropbear_initramfs__config_path }}' directory).
#
# Command line options to pass to dropbear(8)
#
DROPBEAR_OPTIONS="{{ dropbear_initramfs__dropbear_options }}"
#
# On local (non-NFS) mounts, interfaces matching this pattern are
# brought down before exiting the ramdisk to avoid dirty network
# configuration in the normal kernel.
# The special value 'none' keeps all interfaces up and preserves routing
# tables and addresses.
#
#IFDOWN="*"
#
# On local (non-NFS) mounts, the network stack and dropbear are started
# asynchronously at init-premount stage. This value specifies the
# maximum number of seconds to wait (while the network/dropbear are
# being configured) at init-bottom stage before terminating dropbear and
# bringing the network down.
# If the timeout is too short, and if the boot process is not blocking
# on user input supplied via SSHd (ie no remote unlocking), then the
# initrd might pivot to init(1) too early, thereby causing a race
# condition between network configuration from initramfs vs from the
# normal system.
#
#DROPBEAR_SHUTDOWN_TIMEOUT=60

View file

@ -0,0 +1,7 @@
{# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
# Copyright (C) 2017 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
#}
# {{ ansible_managed }}
IP="{{ dropbear_initramfs__network }}"

View file

@ -0,0 +1,27 @@
#!/bin/sh
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
# Copyright (C) 2017 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
# {{ ansible_managed }}
PREREQ=""
prereqs() {
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
{% for name, interface in dropbear_initramfs__combined_interfaces.items() %}
{% set interface_name = (interface.iface | d(name)) %}
ip link set dev {{ interface_name | quote }} down
ip address flush dev {{ interface_name | quote }}
ip route flush dev {{ interface_name | quote }}
{% endfor %}
exit 0

View file

@ -0,0 +1,50 @@
{# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
# Copyright (C) 2017 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
#}
{% import 'templates/import/debops__tpl_macros.j2' as debops__tpl_macros with context %}
#!/bin/sh
# {{ ansible_managed }}
PREREQ=""
prereqs() {
echo "$PREREQ"
}
case $1 in
prereqs)
prereqs
exit 0
;;
esac
{% for name, interface in dropbear_initramfs__combined_interfaces | dictsort %}
{% set interface_name = (interface.iface | d(name)) %}
{% set addresses = (debops__tpl_macros.flattened(interface.address, interface.addresses) | from_yaml) | unique %}
{% set ipv4_addresses = addresses | ansible.utils.ipv4 %}
{% set ipv6_addresses = addresses | ansible.utils.ipv6 %}
{% set gateways = (debops__tpl_macros.flattened(interface.gateway, interface.gateways) | from_yaml) | unique %}
{% set ipv4_gateways = gateways | ansible.utils.ipv4 %}
{% set ipv6_gateways = gateways | ansible.utils.ipv6 %}
ip link set dev {{ interface_name | quote }} up
{% if interface.inet6 in ['static'] %}
{% for address in ipv6_addresses %}
ip addr add {{ address }} dev {{ interface_name | quote }}
{% endfor %}
{% if ipv6_gateways %}
ip route add default via {{ ipv6_gateways | first }}
{% endif %}
{% endif %}
{% if interface.inet in ['static'] %}
{% for address in ipv4_addresses %}
ip addr add {{ address }} dev {{ interface_name | quote }} label {{ interface_name | quote }}:{{ loop.index0 }}
{% endfor %}
{% if ipv4_gateways %}
ip route add default via {{ ipv4_gateways | first }}
{% endif %}
{% endif %}
ip addr show dev {{ interface_name | quote }}
{% endfor %}
exit 0

View file

@ -0,0 +1,181 @@
{# vim: foldmarker=[[[,]]]:foldmethod=marker
# Commonly used set of macros in DebOps.
# It can be included in repositories as needed.
# Changes to this file should go upstream: https://github.com/debops/debops-playbooks/blob/master/templates/debops__tpl_macros.j2
#
# Copyright [[[
# =============
#
# Copyright (C) 2014-2017 Maciej Delmanowski <drybjed@drybjed.net>
# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
# Copyright (C) 2014-2017 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
#
# This file is part of DebOps.
#
# DebOps is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3, as
# published by the Free Software Foundation.
#
# DebOps is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with DebOps. If not, see https://www.gnu.org/licenses/.
#
# ]]]
#
# Usage [[[
# =========
#
# Copy the template file to `./templates/import/debops__tpl_macros.j2` of your
# role and import it from there into various other templates or even use it
# in {{ lookup("template", ...) }}.
#
# Make sure to retain the filename of this file so that automatic updates of
# this file can be implemented.
#
# To use the macros in your own template, this file needs to be included like so:
#
# {% import 'templates/import/debops__tpl_macros.j2' as debops__tpl_macros with context %}
#
# Then you can start using the macros like this:
#
# {{ debops__tpl_macros.indent(some_content, 4) }}
#
# ]]] #}
{% macro get_yaml_list_for_elem(list_or_elem) %}{# [[[ #}
{{ ([ list_or_elem ]
if (list_or_elem is string or list_or_elem in [True, False])
else (list_or_elem | list)) | to_nice_yaml }}
{% endmacro %}{# ]]] #}
{% macro get_realm_yaml_list(domains, fallback_realm) %}{# [[[ #}
{% set custom_realm_list = [] %}
{% if domains and (ansible_local.pki.known_realms | d()) %}
{% for domain in (get_yaml_list_for_elem(domains) | from_yaml) %}
{% if domain in ansible_local.pki.known_realms %}
{% set _ = custom_realm_list.append(domain) %}
{% elif (domain.split('.')[1:] | join('.')) in ansible_local.pki.known_realms %}
{% set _ = custom_realm_list.append(domain.split('.')[1:] | join('.')) %}
{% endif %}
{% endfor %}
{% endif %}
{% if custom_realm_list | length == 0 %}
{% set _ = custom_realm_list.append(fallback_realm) %}
{% endif %}
{{ custom_realm_list | to_nice_yaml }}
{% endmacro %}{# ]]] #}
{% macro get_apache_version() %}{# [[[ #}
{{ ansible_local.apache.version | d("2.4.0") -}}
{% endmacro %}{# ]]] #}
{% macro get_apache_min_version() %}{# [[[ #}
{{ ansible_local.apache.min_version | d("2.4.0") -}}
{% endmacro %}{# ]]] #}
{% macro get_openssl_version() %}{# [[[ #}
{{ ansible_local.pki.openssl_version | d("0.0.0") }}
{% endmacro %}{# ]]] #}
{% macro get_gnutls_version() %}{# [[[ #}
{{ ansible_local.pki.gnutls_version | d("0.0.0") }}
{% endmacro %}{# ]]] #}
{% macro indent(content, width=4, indentfirst=False) %}{# [[[ #}
{# Fixed version of the `indent` filter which does not insert trailing spaces on empty lines.
## Note that you can not use this macro like a filter but have to use it like a regular macro.
## Example: {{ debops__tpl_macros.indent(some_content, 4) }}
##
## Python re.sub seems to default to re.MULTILINE in Ansible.
#}
{{ content | indent(width, indentfirst) | regex_replace("[ \\t\\r\\f\\v]+(\\n|$)", "\\1") -}}
{% endmacro %}{# ]]] #}
{% macro merge_dict(current_dict, to_merge_dict, dict_key='name') %}{# [[[ #}
{% set merged_dict = current_dict %}
{% if to_merge_dict %}
{% if to_merge_dict is mapping %}
{% for dict_name in to_merge_dict.keys() | sort %}
{% if to_merge_dict[dict_name][dict_key] | d() %}
{% set _ = merged_dict.update({to_merge_dict[dict_name][dict_key]:(current_dict[to_merge_dict[dict_name][dict_key]] | d({}) | combine(to_merge_dict[dict_name], recursive=True))}) %}
{% elif to_merge_dict[dict_name][dict_key] is undefined %}
{% set _ = merged_dict.update({dict_name:(current_dict[dict_name] | d({}) | combine(to_merge_dict[dict_name], recursive=True))}) %}
{% endif %}
{% endfor %}
{% elif to_merge_dict is not string and to_merge_dict is not mapping %}
{% set flattened_dict = lookup("flattened", to_merge_dict) %}
{% for element in ([ flattened_dict ] if flattened_dict is mapping else flattened_dict) %}
{% if element[dict_key] | d() %}
{% set _ = merged_dict.update({element[dict_key]:(current_dict[element[dict_key]] | d({}) | combine(element, recursive=True))}) %}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
{{ merged_dict | to_yaml }}
{% endmacro %}{# ]]] #}
{% macro flattened() %}{# [[[ #}
{# This macro does what the flattened lookup from Ansible fails to do in Jinja templates as of Ansible 2.2.
## All macro arguments are flattened into one "flat" list.
## Uses a less known feature of Jinja for using the *args and *kwargs syntax as known from
## Python. Even if the macro does not declare any arguments, it will happyily
## flatten any non-key-value arguments you provide.
## Additional key-value arguments can be used to influence the behavior of the macro.
## The macro uses recursion to flatten nested lists.
## Ref: https://stackoverflow.com/questions/13944751/args-kwargs-in-jinja2-macros
## Usage:
##
## {{ debops__tpl_macros.flattened(['list1', 55, ["deeplist1", "deeplist elem", True, False, undefined], {'mapping': True}], 'raw1', 22, True, False) }}
## → ["list1", 55, "deeplist1", "deeplist elem", true, false, "raw1", 22, true, false]
##
## {{ debops__tpl_macros.flattened(['list1', 55, ["deeplist1", "deeplist elem", True, False, undefined], {'mapping': True}], 'raw1', 22, True, False, filter_undef=False) }}
## → ["list1", 55, "deeplist1", "deeplist elem", true, false, null, "raw1", 22, true, false]
##
## {{ debops__tpl_macros.flattened(['list1', 55, ["deeplist1", "deeplist elem", True, False, undefined], {'mapping': True}], 'raw1', 22, True, False, filter_mapping=False) }}
## → ["list1", 55, "deeplist1", "deeplist elem", true, false, {"mapping": true}, "raw1", 22, true, false]
##
## Ansible versions tested with: 2.1, 2.2
## Jinja versions tested with: 2.8.1
#}
{% set filter_undef = kwargs.filter_undef | d(True) | bool %}
{% set filter_mapping = kwargs.filter_mapping | d(True) | bool %}
{# The following options are planned but currently dont work: #}
{% set append_mapping_keys = kwargs.append_mapping_keys | d(False) | bool %}
{% set append_mapping_values = kwargs.append_mapping_values | d(False) | bool %}
{#
{{ "filter_undef:" + (filter_undef | string) }}
{{ "filter_mapping:" + (filter_mapping | string) }}
{{ "varargs:" + (varargs | string) }}
#}
{% set elem_flattened = [] %}
{% for arg in varargs %}
{#
{{ "arg: " + (arg | string) }}
#}
{% if filter_undef and (arg is undefined) %}
{# Filter out. #}
{% elif append_mapping_keys and (arg is mapping) %}
{# Does not work as of Jinja 2.8? #}
{% set _ = elem_flattened.extend(flattened(arg.keys(), filter_undef=filter_undef, filter_mapping=filter_mapping) | from_yaml) %}
{% elif append_mapping_values and (arg is mapping) %}
{# Does not work as of Jinja 2.8? #}
{% set _ = elem_flattened.extend(flattened(arg.values(), filter_undef=filter_undef, filter_mapping=filter_mapping) | from_yaml) %}
{% elif filter_mapping and (arg is mapping) %}
{# Filter out. #}
{% elif (arg is undefined) %}
{% set _ = elem_flattened.append(None) %}
{% elif (arg is string) or (arg is number) or (arg is sameas True) or (arg is sameas False) or (arg is mapping) %}
{% set _ = elem_flattened.append(arg) %}
{% elif (arg is iterable) %}
{% for element in arg %}
{% set _ = elem_flattened.extend(flattened(element, filter_undef=filter_undef, filter_mapping=filter_mapping) | from_yaml) %}
{% endfor %}
{% endif %}
{% endfor %}
{{ elem_flattened | to_yaml }}
{% endmacro %}{# ]]] #}

View file

@ -0,0 +1,28 @@
{# Copyright (C) 2015-2017 Robin Schneider <ypid@riseup.net>
# Copyright (C) 2017 DebOps <https://debops.org/>
# SPDX-License-Identifier: GPL-3.0-only
#}
{% import 'templates/import/debops__tpl_macros.j2' as debops__tpl_macros with context %}
{% set dropbear_initramfs__tpl_merge_1 = (debops__tpl_macros.merge_dict(dropbear_initramfs__interfaces, dropbear_initramfs__group_interfaces, 'iface') | from_yaml) %}
{% set dropbear_initramfs__tpl_merge_2 = (debops__tpl_macros.merge_dict(dropbear_initramfs__tpl_merge_1, dropbear_initramfs__host_interfaces, 'iface') | from_yaml) %}
{% set dropbear_initramfs__tpl_filtered_interfaces = {} %}
{% for name, params in dropbear_initramfs__tpl_merge_2.items() %}
{% set interface_name = (params.iface | d(name)) %}
{% if params.type is undefined %}
{% if (interface_name.startswith('vlan') or '.' in interface_name) %}
{% set _ = params.update({"type":"vlan"}) %}
{% elif interface_name.startswith(('en','eth')) %}
{% set _ = params.update({"type":"ether"}) %}
{% endif %}
{% endif %}
{% if params.type | d("ether") == 'ether' %}
{% if params.inet is undefined %}
{% set _ = params.update({"inet":"dhcp"}) %}
{% endif %}
{% if params.inet6 is undefined %}
{% set _ = params.update({"inet6":"auto"}) %}
{% endif %}
{% set _ = dropbear_initramfs__tpl_filtered_interfaces.update({interface_name:params}) %}
{% endif %}
{% endfor %}
{{ dropbear_initramfs__tpl_filtered_interfaces | to_yaml }}