てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] 【別解】 Ansibleの呼吸 肆ノ型 フィルター芸「0,1反転」


これは Ansible 3 Advent Calendar 2019 の6日目の記事です。(さかのぼり投稿)


■ はじめに

アドベントカレンダーの 5日目の記事は、既存の 0,1 が書かれているファイルを反転させて別のファイルを生成するという記事でした。

qiita.com

おもわず別解を考えてみたいネタで、「是非 :)」とのことだったので考えました。


■ 使用するファイル

元の記事と同じファイルを用意しおきます。

$ cat before_number.txt
001010101010101010010101
111000101010100111010011
100001010100001010101010
110101010101010010101010
101010100101010101010000
111111100000111010000000


■ Playbook

処理の概要は以下のとおりです。

Playbook は以下のとおりです。

  • main.yml
- hosts: localhost
  connection: local
  gather_facts: no

  tasks:
    # まずそのままコピー
    - name: copy
      copy:
        src: before_number.txt
        dest: after_number.txt

    # 0 と 1 をそれぞれ仮の文字に置換
    - name: replace to temporary chars
      replace:
        path: after_number.txt
        regexp: "{{ item.regexp }}"
        replace: "{{ item.replace }}"
      loop:
        - regexp: 0
          replace: "x"
        - regexp: 1
          replace: "y"  # True にならないようにクォーテーションが必要

    # 仮の文字を反転した 0/1に置換
    - name: replace to 0/1
      replace:
        path: after_number.txt
        regexp: "{{ item.regexp }}"
        replace: "{{ item.replace }}"
      loop:
        - regexp: "x"   # もともと 0 だったところ
          replace: 1    # 1 に置換
        - regexp: "y"   # もともと 1 だったところ
          replace: 0    # 0 に置換


■ Playbook実行

Playbook を実行します

$ ansible-playbook -i localhost, main.yml

PLAY [localhost] **************************************************************************************************

TASK [copy] *******************************************************************************************************
changed: [localhost]

TASK [replace to temporary chars] *********************************************************************************
changed: [localhost] => (item={'regexp': 0, 'replace': 'x'})
changed: [localhost] => (item={'regexp': 1, 'replace': 'y'})

TASK [replace to 0/1] *********************************************************************************************
changed: [localhost] => (item={'regexp': 'x', 'replace': 1})
changed: [localhost] => (item={'regexp': 'y', 'replace': 0})

PLAY RECAP ********************************************************************************************************
localhost                  : ok=3    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

$

作成されたファイルの中身を見てみます。

$ cat after_number.txt
110101010101010101101010
000111010101011000101100
011110101011110101010101
001010101010101101010101
010101011010101010101111
000000011111000101111111

無事に before_number.txt と 0,1 が反転したファイルが生成されました。

おまけ的ですが、after_number.txt の内容が書き換わっていく様子のです。


■ その他考えたこと

この方法に至るまでに考えたことです。

  • せっかく2進数なので、Pythonビット反転の ~ を使えたら良いなと思ったけど、うまく 組み込めなかった
  • replace モジュールを使ってみよう
  • 01 に、10 にいっぺんに置換できればいいけど、できなさそうだ
  • ternayフィルターを使えばできただろうか・・)
  • 2段階の置換でどうにかできた
  • ただ、この方法だと冪等性がなく、毎回 changed になってしまう
  • 中間ファイルの生成処理を挟めばできるかな、まぁいいか。