Saltstack - Передающая переменная содержит одиночные, двойные кавычки, пробел,... в cmd.script?

88
4

У меня есть script, которые используют logger для имитации некоторых "поддельных" логинов:


#!/bin/bash

{%- set maxretry = salt['pillar.get']('fail2ban:maxretry', 3) %}

tag="$1"
message="$2"

logger -p auth.info "The {{ maxretry + 1 }} \"$tag\" below lines are generated by logger to test Fail2ban"

for i in $(seq {{ maxretry + 1 }}); do
logger -p auth.warning -t "$tag" "$message"
done


Он вызывается в макросе:


fake_{{ formula }}_login:
cmd:
- script
- source: salt://fail2ban/fake_login.jinja2
- template: jinja
- args: "{{ tag|default(formula) }} '{{ message }}'"
- require:
- sls: bash
- sls: fail2ban

Вещь {{message}} может содержать одиночные/двойные кавычки, пробел, квадратную скобку,...
Согласно документу cmd.script, чтобы передать строку, содержащую пробел, нам нужно будет дважды ее процитировать.
Но если у меня есть что-то вроде этого:


{{ fail2ban_regex_test('mysql', tag='mysqld', message="150114  3:40:50 [Warning] Access denied for user 'root'@'5.6.7.8' (using password: YES)") }}

он будет регистрироваться в syslog без единой цитаты вокруг пользователя/хоста, просто:


mysqld: 150114  3:40:50 [Warning] Access denied for user root@5.6.7.8 (using password: YES)

что делает fail2ban не распознанным, поскольку он не соответствует регулярному выражению фильтра.


Я могу изменить одиночную кавычку на двойную кавычку и использовать обратную косую черту для выхода:


fake_{{ formula }}_login:
cmd:
- script
- source: salt://fail2ban/fake_login.jinja2
- template:
jinja
- args: "{{ tag|default(formula) }} \"{{ message|safe }}\""

- require:
- sls: bash
- sls: fail2ban


он обрабатывает вышеуказанный случай, когда сообщение содержит только одинарные кавычки.


Но если он содержит двойные кавычки:


{{ fail2ban_regex_test('postfix', tag='postfix/smtpd[20228]', message="NOQUEUE: reject: RCPT from sender.com["5.6.7.8"]: 554 5.7.1 <us...@example.com>: Recipient address rejected: Access denied; from=<us...@sender.com> to=<us...@example.com> proto=ESMTP helo=<mg01d1.sender.com>") }}

Я получил эту ошибку:


local:
Data failed to compile:
----------
Rendering SLS "base:postfix.test" failed: Jinja syntax error: expected token ',', got 'float'; line 29

---
[...]
- sls: openldap
- sls: openldap.diamond
- sls: openldap.nrpe
{%- endcall %}

{{ fail2ban_regex_test('postfix', tag='postfix/smtpd[20228]', message="NOQUEUE: reject: RCPT from sender.com["5.6.7.8"]: 554 5.7.1 <us...@example.com>: Recipie
nt address rejected: Access denied; from=<us...@sender.com> to=<us...@example.com> proto=ESMTP helo=<mg01d1.sender.com>") }} <======================


Если я попытался избежать двойной цитаты с обратной косой чертой:


... message="NOQUEUE: reject: RCPT from sender.com[\"5.6.7.8\"] ...

то я получил еще одну ошибку:


local:
Data failed to compile:
----------
Rendering SLS postfix.test failed, render error: while parsing a block mapping
in "<unicode string>", line 84, column 7:
- args: "postfix/smtpd[20228] \"NO ...
^
expected <block end>, but found '<scalar>'
in "<unicode string>", line 84, column 76:
... : reject: RCPT from sender.com["5.6.7.8"]: 554 5.7.1 <user@examp ...

Как обрабатывать оба случая?

спросил(а) 2021-01-25T19:04:21+03:00 4 месяца, 4 недели назад
1
Решение
88

saltstack расширенные jinja встроенные фильтры с некоторыми настраиваемыми фильтрами:


    yaml_dquote: сериализует строку в правильно спрятанную строку с двойными кавычками YAML.
    yaml_encode: сериализует один объект в скалярном YAML-скаляре с любой необходимой обработкой для экранирования специальных символов.

Что-то вроде:


{%- set foo = 7.7 %}
{%- set bar = none %}
{%- set baz = true %}
{%- set zap = 'The word of the day is "salty".' %}
{%- set zip = '"The quick brown fox . . ."' %}

foo: {{ foo|yaml_encode }}
bar: {{ bar|yaml_encode }}
baz: {{ baz|yaml_encode }}
zap: {{ zap|yaml_encode }}
zip: {{ zip|yaml_dquote }}

предоставит вам:


foo: 7.7
bar: null
baz: true
zap: "The word of the day is \"salty\"."
zip: "\"The quick brown fox . . .\""

С произвольной строкой даже {{ var|yaml_encode|yaml_decode }} может не работать. Лучше, если вы можете кодировать строку, а затем декодировать ее в script.

ответил(а) 2021-01-25T19:04:21+03:00 4 месяца, 4 недели назад
45

У вас есть переменная сообщения, которая может содержать специальные символы.


- args: "{{ tag|default(formula) }} '{{ message }}'"

Я понимаю, что ваш bash script принимает 2 аргумента:


#!/bin/bash
tag=$1
message=$2
echo "$message" #some use of message

Вы вызываете свой script с помощью cmd.script.

Вместо этого вы можете изменить свои сценарии, как показано ниже:


- args: "{{ tag|default(formula) }}"
- stdin: "{{ message }}\n"

& bash script до:


#!/bin/bash
tag=$1
read message
echo "$message" #some use of message

ответил(а) 2021-01-25T19:04:21+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема