1. 程式人生 > >ansible取出register變數中最長字串

ansible取出register變數中最長字串

# 背景 在用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