2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Ansibleタスクのモジュール名をFQCN形式に変換

Last updated at Posted at 2021-03-25

要約

Ansibleタスクのyamlファイルを読んでモジュール名をFQCN形式に変換して保存するスクリプトを紹介します。

解説

Ansible 2.10からタスクでモジュール名をFQCNで書く亊が推奨されるようになった。実際には後方互換のリダイレクタが有効なので、従来の記法でも問題なく動作する。

一件ずつ変更するのはとても面倒なので、ファイルを読み込んでモジュール名を抽出、リダイレクタの設定からFQCNに変換するPythonスクリプトを書いた。全然大したコードではないですが、どうせ書いたからお裾分けします。

機能

  • 指定したディレクトリの指定したglobパターンのファイルを対象として処理する。
  • ファイルをテキストとして読み込んで正規表現で置換するので、YAMLの文法チェックなどは行わない。
  • 各タスクのnameキーの次のキーをモジュール名と見做し、指定したリダイレクタの設定(ansible_builtin_runtime.yml)で変換して書き換える。
    • 従ってnameキーの無いタスクは無視される。
  • debugtemplateなどリダイレクタの設定に無いものは変換しない。
  • 変換の結果ファイル単位で差分があれば上書き保存する。

用意するもの

環境

  • Python 3.7以上
  • Ansible 2.10

情報

以下の三つの情報をスクリプト冒頭の定数に定義する。

  • バージョンアップ先のAnsibleライブラリのansible_builtin_runtime.ymlのパス(例: site-packages/ansible/config/ansible_builtin_runtime.yml)
  • 対象となるAnsibleプロジェクトのディレクトリのパス
  • そのディレクトリからのタスクYAMLを示すglobパターン(例:**/tasks/*.yml)

前述のように確認せずにファイルを書き換えるので、大事なコードを事前にコミットしてワークスペースを綺麗にしておく。

制限事項

  • 本来はプラグインやフィルターもFQCNに変換するべきらしい(リダイレクタを無効にするとこれらも旧名では機能しない)が、あくまでもタスクのみが対象です。
  • 一切の保証はありません。ころんでも泣かない。

参考

実行例

対象のタスクファイル

---

- hosts: win_host
  gather_facts: yes
  tasks:
    - name: get terminal service behaviour on failure
      win_command: sc qfailure TermService
      register: qfailure
      changed_when: no

    - name: debug
      debug: var=qfailure

実行

$ python convert2fqcn.py
processing old.yml
  checking win_command...
    converted to ansible.windows.win_command
  checking debug...
    not found.

結果

win_commandansible.windows.win_commandに変換された。値の部分は変更されていない。またdebugも変換されていない。

差分を表示する為に変換前後でファイル名を変えているが、実際には上書きするのでご注意下さい。

--- old.yml	2021-03-25 10:01:46.297632163 +0900
+++ new.yml	2021-03-25 09:55:20.492025609 +0900
@@ -7 +7 @@
-      win_command: sc qfailure TermService
+      ansible.windows.win_command: sc qfailure TermService

スクリプト

convert2fqcn.py
from pathlib import Path
import re
import yaml

'''
python  convert2fqcn.py

Ansibleタスクのモジュール名をFQCN形式に変換します。以下に指定したディレクトリ配下に見つかった
ファイルを直接書き換えます。

'''


# Ansibleモジュールのリダイレクト用config 'ansible_builtin_runtime.yml'へのパス
CONVERTION_MAP_PATH = './ansible-2.10-venv/lib/python3.6/site-packages/ansible/config/ansible_builtin_runtime.yml.back'
# 置換を行うパス
TARGET_DIR = 'roles/'
# 置換を行うタスクファイルのglobパターン。前項からの相対パスで表す。
TASKS_GLOB_PATTERN = '**/tasks/*.yml'

map_cache = {}

# nameキーで始まるオブジェクトにマッチ
name_line_regex = ' *- name:.*\n'
# 次の行のコロンまでをモジュール名と判定
module_line_regex = '([\S_]+):'
module_name_regex = f'({ name_line_regex } *){module_line_regex}'


def main():
    role_path = Path(TARGET_DIR).rglob(TASKS_GLOB_PATTERN)
    for path in role_path:
        with open(path, 'r') as role_file:
            print(f'processing {path}')
            task_data = role_file.read()
            new_task_data = replace(task_data)
        if new_task_data != task_data:
            with open(path, 'w') as role_file:
                role_file.write(new_task_data)


def load_covertion_map(convertion_map_path):
    runtime_data = yaml.load(open(convertion_map_path))
    lis = runtime_data.get('plugin_routing').get('modules')
    return lis


def replace(task_data):
    r = re.compile(module_name_regex)
    return re.sub(r, convert_task, task_data)


def convert_task(match_obj):
    res = None
    if match_obj.groups():
        prev_lines, old_key = match_obj.groups()
        print(f'  checking {old_key}...')
        entry = query(old_key)
    else:
        # マッチしなければ呼ばれないのでここには来ないはず。
        return None
    if entry:
        new_key = entry.get('redirect')
        print(f'    converted to {new_key}')
        key = new_key
    else:
        print('    not found.')
        key = old_key
    # キー区切りのコロンまでマッチしているので必ず付ける。
    return prev_lines + key + ':'


def query(key):
    cached = map_cache.get(key)
    if cached:
        return cached
    entry = CONVERTION_MAP.get(key)
    map_cache[key] = entry
    return entry


if __name__ == '__main__':
    CONVERTION_MAP = load_covertion_map(CONVERTION_MAP_PATH)
    main()

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?