21 Commits
1.0.0 ... 2.1.2

Author SHA1 Message Date
9cf80214ee Merge pull request #5 from claranet/feat/newest-distrib-support
feat: newest distrib support
2023-08-07 13:28:54 +02:00
68c3f15171 fix: update testing badge for show CI result 2023-08-07 12:39:30 +02:00
7c53a18c21 feat: upgrade molecule to v5 2023-08-07 12:26:04 +02:00
8eb3096a5e fix: remove flake8 as verifier for lint 2023-08-07 12:25:44 +02:00
eaff8d03a5 fix: ansible-lint errors 2023-08-07 12:25:13 +02:00
28a61e55fa fix: lint error by fecthing last content from cookiecutter 2023-08-07 12:24:38 +02:00
b2ad104eec downgrade to ubuntu 20.04 due to docker bug with latest systemd 2022-08-22 17:31:37 +02:00
8c21123d4f move tasks from configure_motd.yml to main.yml 2022-08-22 16:41:24 +02:00
8382c9f3f3 update molecule scenarios 2022-08-22 16:40:40 +02:00
eb57d613dc remove banner variables 2022-07-06 10:04:17 +02:00
dc8567c979 add git_branch 2022-07-06 10:00:08 +02:00
e797037846 Up to 1.2.1 for Galaxy action 2022-06-29 15:46:05 +02:00
92cb5bf55e Merge pull request #4 from claranet/remove_banner
Remove banner reference
2022-06-29 11:29:16 +02:00
9770e5d43c Change Centos to fedora for molecule test 2022-06-29 11:22:50 +02:00
cf7e3da48e Remove banner reference 2022-06-29 10:55:26 +02:00
dbf4d327cf split tasks 2021-10-05 11:46:18 +02:00
6a42daba46 update readme 2021-10-04 09:47:04 +02:00
86a0ea5917 update motd url 2021-09-30 11:51:27 +02:00
e3144338e6 remove default values 2021-09-29 17:21:52 +02:00
53faa7d96b fix motd template 2021-09-29 17:04:04 +02:00
ea56ef6c69 Remote MOTD 2021-09-29 16:57:02 +02:00
17 changed files with 176 additions and 258 deletions

View File

@ -2,44 +2,45 @@
exclude_paths:
- molecule/
- .pre-commit-config.yaml
- .github/
parseable: true
use_default_rules: true
enable_list:
command-shell: # Specific to use of command and shell modules
# Specific to use of command and shell modules
- command-instead-of-module
- command-instead-of-shell
- deprecated-command-syntax
- inline-env-var
- no-changed-when
- risky-shell-pipe
core: # Related to internal implementation of the linter
# Related to internal implementation of the linter
- internal-error
- load-failure
- parser-error
- syntax-check
deprecations: # Indicate use of features that are removed from Ansible
# Indicate use of features that are removed from Ansible
- deprecated-bare-vars
- deprecated-command-syntax
- deprecated-local-action
- deprecated-module
- no-jinja-when
- role-name
formatting: # Related to code-style
# Related to code-style
- no-jinja-nesting
- no-tabs
- playbook-extension
- risky-octal
- var-spacing
- yaml
idempotency: # Possible indication that consequent runs would produce different results
# Possible indication that consequent runs would produce different results
- git-latest
- hg-latest
- no-changed-when
- package-latest
idiom: # Anti-pattern detected, likely to cause undesired behavior
# Anti-pattern detected, likely to cause undesired behavior
- command-instead-of-module
- command-instead-of-shell
- empty-string-compare
@ -50,17 +51,15 @@ enable_list:
- no-relative-paths
- unnamed-task
- var-naming
metadata: # Invalid metadata, likely related to galaxy, collections or roles
# Invalid metadata, likely related to galaxy, collections or roles
- meta-incorrect
- meta-no-tags
- meta-video-links
- role-name
unpredictability:
- ignore-errors
- partial-become
unskippable:
- syntax-check
yaml: # External linter which will also produce its own rule codes.
# External linter which will also produce its own rule codes.
- yaml
warn_list:
@ -70,5 +69,6 @@ warn_list:
skip_list:
- role-name # BUG
- name[casing]
verbosity: 1

View File

@ -10,6 +10,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: galaxy
uses: robertdebock/galaxy-action@1.1.1
uses: robertdebock/galaxy-action@1.2.1
with:
galaxy_api_key: ${{ secrets.galaxy_api_key }}
git_branch: main

View File

@ -8,43 +8,77 @@ on: # yamllint disable-line rule:truthy
pull_request:
jobs:
setup:
name: Setup scenarios matrix
runs-on: ubuntu-22.04
outputs:
scenarios: ${{ steps.matrix.outputs.scenarios }}
steps:
- uses: actions/checkout@v3
- id: matrix
run: |
JSON="["
for s in $(find molecule -mindepth 1 -maxdepth 1 -type d -exec basename "{}" \;); do
JSON="${JSON}\"${s}\","
done
JSON="${JSON%?}"
JSON="$JSON]"
echo "::set-output name=scenarios::$(echo $JSON)"
lint:
runs-on: ubuntu-20.04
name: Lint
needs:
- setup
runs-on: ubuntu-22.04
steps:
- name: checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: "${{ github.repository }}"
- name: molecule
uses: robertdebock/molecule-action@2.6.17
- name: Run ansible lint
uses: ansible/ansible-lint-action@main
with:
command: lint
path: "."
test:
name: Scenario "${{ matrix.scenario }}" on ${{ matrix.config.image }}:${{ matrix.config.tag }}
needs:
- lint
- setup
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
scenario: ${{ fromJson(needs.setup.outputs.scenarios) }}
config:
- image: "amazonlinux"
tag: "latest"
- image: "centos"
tag: "8"
- name: "redhat"
image: "registry.access.redhat.com/ubi8/ubi"
tag: "latest"
- image: "debian"
tag: "12"
- image: "debian"
tag: "11"
- image: "debian"
tag: "10"
- image: "ubuntu"
tag: "20.04"
tag: "22.04"
steps:
- name: checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: "${{ github.repository }}"
- name: molecule
uses: robertdebock/molecule-action@2.6.17
uses: gofrolist/molecule-action@v2
with:
# molecule_options: --debug
molecule_command: test
molecule_args: --scenario-name ${{ matrix.scenario }} -d docker
molecule_working_dir: "${{ github.repository }}"
env:
image: ${{ matrix.config.image }}
tag: ${{ matrix.config.tag }}

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
###VSCode###
.vscode
###MacOS###
.DS_Store

View File

@ -2,21 +2,22 @@
[![Maintainer](https://img.shields.io/badge/maintained%20by-claranet-e00000?style=flat-square)](https://www.claranet.fr/)
[![License](https://img.shields.io/github/license/claranet/ansible-role-motd?style=flat-square)](LICENSE)
[![Release](https://img.shields.io/github/v/release/claranet/ansible-role-motd?style=flat-square)](https://github.com/claranet/ansible-role-motd/releases)
[![Status](https://img.shields.io/github/workflow/status/claranet/ansible-role-motd/Ansible%20Molecule?style=flat-square&label=tests)](https://github.com/claranet/ansible-role-motd/actions?query=workflow%3A%22Ansible+Molecule%22)
[![Status](https://img.shields.io/github/actions/workflow/status/claranet/ansible-role-motd/molecule.yml?style=flat-square&label=tests&branch=main)](https://github.com/claranet/ansible-role-motd/actions?query=workflow%3A%22Ansible+Molecule%22)
[![Ansible version](https://img.shields.io/badge/ansible-%3E%3D2.9-black.svg?style=flat-square&logo=ansible)](https://github.com/ansible/ansible)
[![Ansible Galaxy](https://img.shields.io/badge/ansible-galaxy-black.svg?style=flat-square&logo=ansible)](https://galaxy.ansible.com/claranet/motd)
> :star: Star us on GitHub — it motivates us a lot!
Install and configure dynamic MOTD and SSH banner
Install and configure dynamic MOTD
This role uses [https://github.com/claranet/motd](https://github.com/claranet/motd) by default to get the MOTD
```
System info:
Hostname·········: claranet_motd_ubuntu-20.04
Distro···········: Ubuntu 20.04.3 LTS
Kernel···········: Linux 5.10.47-linuxkit
Updates available: 6 (2 security)
Uptime···········: up 2 days, 23 hours, 18 minutes
Load·············: 1.33 (1m), 0.43 (5m), 0.20 (15m)
Processes········: 13 (root), 3 (user), 16 (total)
@ -34,7 +35,7 @@ Ansible:
## :warning: Requirements
Ansible >= 2.9
Ansible >= 2.10
## :zap: Installation
@ -45,10 +46,13 @@ ansible-galaxy install claranet.motd
## :gear: Role variables
Variable | Default value | Description
--------------------------|-----------------------|----------------------------------------
-----------------------------|------------------------------------------------------------------------|----------------------------------------------------------------
motd_disable_default_motd | true | Disable system default MOTD (/etc/motd)
motd_banner_template | etc/banner | SSH banner template
motd_template | usr/local/bin/dynmotd | Dynmaic MOTD template
motd_template | https://raw.githubusercontent.com/claranet/motd/master/scripts/00-basic| Dynmaic MOTD template<br>Can be a URL or a local template
motd_template_prepend | "" | Prepend raw content to `motd_template`
motd_template_append | See [defaults/main.yml](defaults/main.yml) | Append raw content to `motd_template`
motd_template_username | "" | Used when `motd_template` is an URL
motd_template_password | "" | Used when `motd_template` is an URL
## :pencil2: Example Playbook
@ -56,7 +60,8 @@ motd_template | usr/local/bin/dynmotd | Dynmaic MOTD template
---
- hosts: all
roles:
- claranet.motd
- role: claranet.motd
motd_template: "{{ playbook_dir }}/templates/dynmotd.j2"
```
## :closed_lock_with_key: [Hardening](HARDENING.md)

View File

@ -1,4 +1,12 @@
---
motd_disable_default_motd: true
motd_banner_template: etc/banner
motd_template: usr/local/bin/dynmotd
motd_template: https://raw.githubusercontent.com/claranet/motd/master/scripts/00-basic
motd_template_prepend: ""
motd_template_append: |
echo -e "\e[0;39mAnsible:
Last deployment\e[2m···\e[0m: {{ ansible_date_time.iso8601_micro }}
"
motd_template_username: ""
motd_template_password: ""

View File

@ -1,4 +1,4 @@
- name: Restart sshd
service:
ansible.builtin.service:
name: sshd
state: restarted

View File

@ -7,7 +7,7 @@ galaxy_info:
license: "MPL2"
min_ansible_version: 2.9
min_ansible_version: "2.10"
galaxy_tags: ['claranet', 'motd', 'system', 'dynmotd', 'dynamic']

View File

@ -14,8 +14,11 @@ ENV {{ var }} {{ value }}
{% endfor %}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python3 sudo bash ca-certificates iproute2 systemd && apt-get clean; \
elif [ $(command -v yum) ]; then yum install -y python3 sudo bash iproute systemd firewalld initscripts; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python3 sudo bash ca-certificates iproute2 systemd wget && apt-get clean; \
elif [ $(command -v yum) ]; then yum install -y python3 sudo bash iproute systemd initscripts wget; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 wget && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates wget; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 wget && xbps-remove -O; fi
RUN wget -O /usr/bin/systemctl https://raw.githubusercontent.com/gdraheim/docker-systemctl-replacement/master/files/docker/systemctl3.py && \
chmod +x /usr/bin/systemctl

View File

@ -3,15 +3,14 @@
hosts: all
roles:
- role: claranet.motd
motd_banner_template: null
pre_tasks:
- name: "Update APT cache"
apt:
ansible.builtin.apt:
update_cache: true
when:
- ansible_pkg_mgr == "apt"
- name: Install sshd
package:
ansible.builtin.package:
name: openssh-server

View File

@ -1,12 +1,15 @@
---
dependency:
name: galaxy
name: shell
command: python3 -m pip install pytest-testinfra
driver:
name: docker
platforms:
- name: claranet_motd_${image:-debian}-${tag:-latest}
# On "${name:-${image:-debian}", the last brace does not miss, it works like that...
# The env var should be used when the image variable refers to a full registry path like registry.access.redhat.com/ubi8/ubi
- name: claranet_motd_${name:-${image:-debian}-${tag:-latest}-${scenario:-default}
image: ${image:-debian}:${tag:-latest}
privileged: true
tty: true
@ -29,8 +32,6 @@ provisioner:
verifier:
name: testinfra
lint:
name: flake8
options:
verbose: true
s: true

View File

@ -12,11 +12,6 @@ motd_file_path = "/usr/local/bin/dynmotd"
pam_line = f"session optional pam_exec.so type=open_session stdout {motd_file_path}"
def test_banner_file(host):
file = host.file("/etc/banner")
assert not file.exists
def test_motd_file(host):
file = host.file(motd_file_path)
assert file.exists

View File

@ -0,0 +1,22 @@
---
- name: disable_default_motd | Get stats of {{ _motd_sshd_config_file_path }}
ansible.builtin.stat:
path: "{{ _motd_sshd_config_file_path }}"
register: _motd_sshd_config_file_stat
- name: disable_default_motd | Ensure PrintMotd is set to "no" in {{ _motd_sshd_config_file_path }}
ansible.builtin.lineinfile:
path: "{{ _motd_sshd_config_file_path }}"
regexp: "^PrintMotd "
line: PrintMotd no
when: _motd_sshd_config_file_stat.stat.exists
- name: disable_default_motd | Comment out pam_motd in pam
ansible.builtin.replace:
path: "{{ item }}"
regexp: '^(session\s+optional\s+pam_motd.so\s+.*)'
replace: '# \1'
loop:
- "{{ _motd_pam_login_file_path }}"
- "{{ _motd_pam_sshd_file_path }}"
...

View File

@ -1,47 +1,11 @@
---
- block:
- name: Get stats of {{ _motd_sshd_config_file_path }}
stat:
path: "{{ _motd_sshd_config_file_path }}"
register: _motd_sshd_config_file_stat
- name: Ensure PrintMotd is set to "no" in {{ _motd_sshd_config_file_path }}
lineinfile:
path: "{{ _motd_sshd_config_file_path }}"
regexp: "^PrintMotd "
line: PrintMotd no
when: _motd_sshd_config_file_stat.stat.exists
- name: Comment out pam_motd in pam
replace:
path: "{{ item }}"
regexp: '^(session\s+optional\s+pam_motd.so\s+.*)'
replace: '# \1'
loop:
- "{{ _motd_pam_login_file_path }}"
- "{{ _motd_pam_sshd_file_path }}"
- name: Include disable_default_motd.yml if motd_disable_default_motd is True
ansible.builtin.include_tasks: disable_default_motd.yml
when: motd_disable_default_motd|bool
- name: Apply template {{ motd_banner_template }} on {{ _motd_banner_file_path }}
template:
src: "{{ motd_banner_template }}"
dest: "{{ _motd_banner_file_path }}"
owner: root
group: root
mode: '0644'
when: motd_banner_template
- name: Ensure line "Banner {{ _motd_banner_file_path }}" is {{ _motd_banner_state }} in {{ _motd_sshd_config_file_path }}
lineinfile:
path: "{{ _motd_sshd_config_file_path }}"
regexp: "^(#?)Banner "
line: Banner {{ _motd_banner_file_path }}
state: "{{ _motd_banner_state }}"
notify: Restart sshd
- name: Apply template {{ motd_template }} on {{ _motd_file_path }}
template:
src: "{{ motd_template }}"
- name: "Configure_motd | Apply template {{ motd_template + ' in ' + _motd_file_path }}"
ansible.builtin.copy:
content: "{{ motd_template_prepend + _motd_template_content + motd_template_append }}"
dest: "{{ _motd_file_path }}"
owner: root
group: root
@ -49,10 +13,11 @@
tags:
- molecule-idempotence-notest
- name: Add pam_exec {{ _motd_file_path }} in pam
lineinfile:
- name: Configure_motd | Add in pam pam_exec {{ _motd_file_path }}
ansible.builtin.lineinfile:
path: "{{ item }}"
line: session optional pam_exec.so type=open_session stdout {{ _motd_file_path }}
loop:
- "{{ _motd_pam_login_file_path }}"
- "{{ _motd_pam_sshd_file_path }}"
...

View File

@ -1,32 +0,0 @@
,╓╗╖æææææ╖╖,
,╗╣╬╬╣╝╜╙╙"╙╙╜╝╣Ñ╬æ╖
╓╣╬╝╜ "╙╣╬╣µ
╓╬╬M "╢╬╣,
╣╬╝ ╣Ñæ ╙╬╬╖╖╖╖╖╓,
,,╓╣╬M ,╗ ╬╬╬ ╓╖, ╝╜╜╜╜╝╣╬╬╣╖
╓æ╣Ñ╬╣╝╝╝ ╓╣╬╝ ╬╬╬ ²╣╬╣µ `╙╣╬æ,
╓╣╬╝^ ╣╬╝ ╬╬╬ `╣╬æ ╙╬╬φ
╣╬M ║╬╬ ╢╣M ╬╬U ╢╬φ
╬╬M ║╬╬ ╬╬M ╬╬∩
║╬╬ "╬ѵ ╓Ñ╬ ╟╬┼
╟╬┼ `╣╬╖, ,╢╬╣ ╟╬┼
║╬╬ ╙╢╬╬╣ææ╬╣╬╬╝` ╬╬M
╬╬µ `"""` ╣╬M
`╬╬φ ╓╬╬M
╚╬╬╖, ,╗╣╬╝
╙╣Ñ╬╣æ╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖╖æ╣╬╬╝╜
`"╙╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╜╙" ®
╖╖┬ ╓╖╖
╬╬M ╓╬╬
,╗╣╬╬╣æ, ╬╬M ,æ╣╬╬╬æ╖ ß╣ß╓æ╣ ╓æ╣╬╬╣æ, -╣╣╓æ╣╬╣╖ ,╖╣╬╬╣╖, ╢╣╬╬╣╣
║╬╬" `╝╜* ╬╬M ╝╝┘ ╟╬φ ╬╬╬M"` ª╝╝ ╙╬Ñ "╬╬M ║╬╬ ╢╬M ╢╬φ ╓╬╬
-╬╬H ╬╬M ╓æ╣╬╬╣╬╬M ╬╬╬ ╗╢╣╬╣╣╬╬⌐ "╬╬ ╓╬╬ ╬╬╬╬╬╬╬╬╬╬ ╓╬╬
╢╬φ ╓,, ╬╬M ╢╬M ╟╬M ╬╬╪ ╬╬M ,╬╬⌐ "╬╬ ╓╬╬ ╬╬φ ╓ ╓╬╬
╚╬╬╣╣╣╬╝ ╬╬M ╙╣╬╣æ╣╬╬╬M ╬╬╪ ║╬╬ææ╣╣╬╬⌐ "╬╬ ╓╬╬ ╚╬╬╣╣╣╬╣╜ '╬╬╣æ
`` `` ``` ``` ```
WARNING : Unauthorized access to this system is forbidden and will be
prosecuted by law. By accessing this system, you agree that your actions
may be monitored if unauthorized usage is suspected.

View File

@ -1,85 +0,0 @@
#!/bin/bash
# get load averages
IFS=" " read LOAD1 LOAD5 LOAD15 <<<$(awk '{ print $1,$2,$3 }' /proc/loadavg)
# get free memory
IFS=" " read USED AVAIL TOTAL <<<$(free -htm | grep "Mem" | awk {'print $3,$7,$2'})
# get processes
PROCESS=$(ps -eo user=|sort|uniq -c | awk '{ print $2 " " $1 }')
PROCESS_ALL=$(echo "$PROCESS"| awk {'print $2'} | awk '{ SUM += $1} END { print SUM }')
PROCESS_ROOT=$(echo "$PROCESS"| grep root | awk {'print $2'})
PROCESS_USER=$(echo "$PROCESS"| grep -v root | awk {'print $2'} | awk '{ SUM += $1} END { print SUM }')
# get processors
PROCESSOR_NAME=$(grep "model name" /proc/cpuinfo | cut -d ' ' -f3- | awk {'print $0'} | head -1)
PROCESSOR_COUNT=$(grep -ioP 'processor\t:' /proc/cpuinfo | wc -l)
LOCAL_IP_ADDRESSES=$(hostname -I | sed 's/ /\n\ /g' | sed '/^[[:space:]]*$/d')
# Processing available updates with yum is too long
{% if ansible_pkg_mgr == "apt" %}
UPDATES_AVAILABLE=$(apt list --upgradable 2>/dev/null)
UPDATES_AVAILABLE_NB=$(echo -e "$UPDATES_AVAILABLE" | wc -l)
SECURITY_UPDATES_AVAILABLE_NB=$(echo -e "$UPDATES_AVAILABLE" | grep "\-security" | wc -l)
{% endif %}
# colors
W="\e[0;39m"
G="\e[1;32m"
R="\e[1;31m"
dim="\e[2m"
undim="\e[0m"
echo -e "${W}System info:
$W Hostname$dim·········$undim: $W${HOSTNAME}
$W Distro$dim···········$undim: $W$(grep "PRETTY_NAME" /etc/*release | cut -d "=" -f 2- | sed 's/"//g')
$W Kernel$dim···········$undim: $W$(uname -sr)
{% if ansible_pkg_mgr == "apt" %}
$W Updates available: $W$UPDATES_AVAILABLE_NB ($SECURITY_UPDATES_AVAILABLE_NB security)
{% endif %}
$W Uptime$dim···········$undim: $W$(uptime -p)
$W Load$dim·············$undim: $G$LOAD1$W (1m), $G$LOAD5$W (5m), $G$LOAD15$W (15m)
$W Processes$dim········$undim: $G$PROCESS_ROOT$W (root), $G$PROCESS_USER$W (user), $G$PROCESS_ALL$W (total)
$W CPU$dim··············$undim: $W$PROCESSOR_NAME ($G$PROCESSOR_COUNT$W vCPU)
$W Memory$dim···········$undim: $G$USED$W used, $G$AVAIL$W avail, $G$TOTAL$W total
$W Local IPs$dim········$undim: $LOCAL_IP_ADDRESSES$W"
# config
max_usage=90
bar_width=50
# disk usage: ignore zfs, squashfs & tmpfs
mapfile -t dfs < <(df -H -x zfs -x squashfs -x tmpfs -x devtmpfs -x overlay --output=target,pcent,size | tail -n+2)
printf "\nDisk usage:\n"
for line in "${dfs[@]}"; do
# get disk usage
usage=$(echo "$line" | awk '{print $2}' | sed 's/%//')
used_width=$((($usage*$bar_width)/100))
# color is green if usage < max_usage, else red
if [ "${usage}" -ge "${max_usage}" ]; then
color=$R
else
color=$G
fi
# print green/red bar until used_width
bar="[${color}"
for ((i=0; i<$used_width; i++)); do
bar+="="
done
# print dimmmed bar until end
bar+="${W}${dim}"
for ((i=$used_width; i<$bar_width; i++)); do
bar+="·"
done
bar+="${undim}]"
# print usage line & bar
echo "${line}" | awk '{ printf("%-31s%+3s used out of %+4s\n", $1, $2, $3); }' | sed -e 's/^/ /'
echo -e "${bar}" | sed -e 's/^/ /'
done
printf "\n"
echo -e "${W}Ansible:
${W} Last deployment$dim···$undim: {{ ansible_date_time.iso8601_micro }}
"

View File

@ -2,6 +2,6 @@
_motd_sshd_config_file_path: /etc/ssh/sshd_config
_motd_pam_login_file_path: /etc/pam.d/login
_motd_pam_sshd_file_path: /etc/pam.d/sshd
_motd_banner_file_path: /etc/banner
_motd_banner_state: "{{ 'present' if motd_banner_template else 'absent' }}"
_motd_file_path: /usr/local/bin/dynmotd
_motd_lookup_method: "{{ 'url' if motd_template is match('http(s)?:\/\/') else 'template' }}"
_motd_template_content: "{{ lookup(_motd_lookup_method, motd_template, split_lines=False, username=motd_template_username, password=motd_template_password) }}"