ansible取出register變數中最長字串
阿新 • • 發佈:2020-06-04
# 背景
在用ansible撰寫一個etcd恢復的playbook時,有一個操作是獲取etcd啟動時的"initial-cluster"啟動引數,該引數在etcd叢集不同節點不一致,需要取出etcd節點啟動引數中最長的作為etcdctl snapshot restore的引數。
```bash
[root@tke-init ansible]# cat etcd.hosts
[etcd]
10.0.32.79
10.0.32.41
10.0.32.97
[snapshot]
10.0.32.79 recoverySnapFile=/alauda/etcd_bak/snap-202005250843.db
[root@tke-init ansible]# cat c.yaml
---
- name: etcd snapshot recovery
gather_facts: false
hosts: all
tasks:
- name: get the initial-cluster info
shell: |+
cat /etc/kubernetes/manifests/etcd.yaml |grep "initial-cluster="|sed 's/.*initial-cluster=//'
register: initialCluster
- debug:
msg: "{{initialCluster.stdout}}"
```
> 如下圖,需要取出圈出的最長的字串。
![](https://360linux.oss-cn-hangzhou.aliyuncs.com/img/image-20200602063408560.png)
# 實現
## shell方式
```bash
[root@tke-init ansible]# cat c.yaml
---
- name: etcd snapshot recovery
gather_facts: false
hosts: all
tasks:
- name: get the initial-cluster info
shell: |+
cat /etc/kubernetes/manifests/etcd.yaml |grep "initial-cluster="|sed 's/.*initial-cluster=//'
register: initialCluster
- debug:
msg: "{{initialCluster.stdout}}"
- name: if the /tmp/a.txt exist,remove it
file:
path: /tmp/a.txt
state: absent
force: yes
run_once: true
delegate_to: localhost
- name: echo the all initialCluster parameter to localhost
shell: |+
echo "{{item}}" >>/tmp/a.txt
with_items:
- "{{ initialCluster.stdout }}"
delegate_to: localhost
- name: get the longest initial-cluster paramaters
shell:
cat /tmp/a.txt |awk '{print length($0),$0}'|sort -k1 -rn|head -1|awk '{print $2}'
register: maxInitialCluster
run_once: true
delegate_to: localhost
- debug:
msg: "{{ maxInitialCluster.stdout }}"
```
> 執行測試如下
![image-20200602071324775](https://360linux.oss-cn-hangzhou.aliyuncs.com/img/image-20200602071324775.png)
## ansible過濾器方式
```bash
[root@tke-init ansible]# cat bb.yaml
---
- name: test
gather_facts: false
hosts: all
tasks:
- name: get the initial-cluster info
shell: |+
cat /etc/kubernetes/manifests/etcd.yaml |grep "initial-cluster="|sed 's/.*initial-cluster=//'
register: initialCluster
- set_fact:
combined_initialCluster: "{{ groups['etcd'] |map('extract',hostvars,['initialCluster','stdout']) |list |join(',') }}"
- set_fact:
final_initialCluster: "{{ combined_initialCluster.split(',')|unique|join(',') }}"
- debug:
var: final_initialCluster
```
> 執行測試如下
![image-20200603205659615](https://360linux.oss-cn-hangzhou.aliyuncs.com/img/image-20200603205659615.png)
# 總結
1. shell方式來說,雖然比較繞,但是更加通用;ansible過濾器方式,其中有一個unique的filter,只適用本次場景中正好有重複列表元素的情況,如果每個節點的register取回的字串完全不一致,則無法適用。
2. 取回全部register的字串組合成一個list後,原本計劃使用max過濾器取出列表中最長的字串元素,發現max過濾器無法傳遞key引數,而python原生的max方法是支援傳遞key引數的。
![image-20200603211020953](https://360linux.oss-cn-hangzhou.aliyuncs.com/img/image-20200603211020953.png)
![image-20200603211209293](https://360linux.oss-cn-hangzhou.aliyuncs.com/img/image-20200603211209