2015-03-19 66 views
3

我有使用logger模擬一些「假」登錄腳本:saltstack - 傳遞變量包含單引號,雙引號,空格...到cmd.script?

#!/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 

事情是{{消息}}可以包含單/雙引號,空格,方括號,... 根據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)") }} 

將被記錄到系統日誌而沒有圍繞用戶/主機的單引號,只是:

mysqld: 150114 3:40:50 [Warning] Access denied for user [email protected] (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 <[email protected]>: Recipient address rejected: Access denied; from=<[email protected]> to=<[email protected]> 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 <[email protected]>: Recipie 
nt address rejected: Access denied; from=<[email protected]> to=<[email protected]> 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 <[email protected] ... 

如何處理這兩種情況?

+1

如何傳遞一個串過'stdin'及使用'read'來把它讀入一個變量。然後在雙引號內使用該變量... – anishsane 2015-03-19 04:31:11

+0

全部自動化。這裏沒有涉及到stdin。 – quanta 2015-03-19 04:46:38

+0

我的理解是這樣的:你有你的框架中的字符串數據,使用它,你想觸發另一個腳本。您正在使用一些字符串連接邏輯來完成此操作。取而代之的是,改變'另一個腳本'以從標準輸入讀取數據。然後,不要使用字符串連接,而是將字符串傳遞給腳本。 – anishsane 2015-03-19 09:29:49

回答

3

saltstack擴展jinja內置過濾器與一些custom filters

  • 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 }}可能無法正常工作。如果你可以對字符串進行編碼,然後用腳本進行解碼,那就更好了。

+0

'yaml_dquote'只是轉換爲雙引號,並用反斜槓轉義字符串內的雙引號。這與我所嘗試的相同,實際上,我得到了同樣的錯誤。 – quanta 2015-03-25 14:53:39

+0

thankyouthankyouthankyou,你讓我的星期五:) – Rumbles 2016-04-29 19:13:10

0

你有消息變量,它可以包含特殊字符。

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

我的理解是,你的bash腳本需要兩個參數:

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

要調用與cmd.script腳本。

取而代之的是,你也許可以改變你的腳本如下:

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

& bash腳本到:

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