ansiblelint.AnsibleLintRule

# 概要
AnsibleのカスタムLintを作成するために必要な情報のまとめ。
=ansiblelint.AnsibleLintRuleの動作


## 基本構成

ansiblelint.AnsibleLintRuleを継承したクラスで、match()関数、matchtasks()関数をオーバーライドし、その関数内でチェック処理を実装する。

<img width="182" alt="スクリーンショット 2020-02-17 13.31.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423287/aec75df3-26d6-5d65-91df-deb8e8bb685a.png">


## サンプル構成

プレイブックの構成は以下の通り

``` command
# tree ./
./
├── child.yml
├── roles
│   └── role01
│       ├── tasks
│       │   └── main.yml
│       └── vars
│           └── main.yml
└── test.yml
```

``` ./test.yml
 ---
 - hosts: all
   tasks:
     - name: set_fact simasu
       set_fact:
         my_fact: "this is my fact"

     - name: debug shimasu
       debug:
          msg: "{{ my_fact }}"
  roles:
    - role01

- name: import other playbook
  import_playbook: child.yml
     17 
```

``` ./roles/role01/tasks/main.yml
- name: "debug messag"
  debug:
    msg: "{{ test_var01 }}"

- name: debug
  debug:
    msg: "{{ role01_vars_var }}"

- name: set_fact test
   set_fact:
     my_role_fact: "this is fact var defined in role01 fact"
```

``` roles/role01/vars/main.yml
role01_vars_var: "this is role01 var in vars"
SVG_role01_var: "this is role01 var in vars"
```

``` ./child.yml
---
- hosts: all
  tasks:
    - debug:
        msg: "called child.yml"
```

## 基本ルール
- Lint処理を定義するAnsibleLintRuleを継承した任意のクラスを定義する。
- クラスでは、以下のいずれかのメソッドを呼び出す
  - match(self,file,lines)
  - matchtasks(self,file,tasks)


``` InvalidRoleVariableNameRule.py
class InvalidRoleVariableNameRule(AnsibleLintRule):
    id = 'CUSTOMRULE3.5.1'
    shortdesc = 'Invalid role variable name'
    description = 'Check for lines that have invalid role variable name'
    tags = {'formatting'}

    def matchtask(self, file, task):
        print("-----file-----")
        print(file)
        print("-----task-----")
        print(task)

        return False

    def match(self, file, line):
        print("-----file-----")
        print(file)
        print("-----line-----")
        print(line)
        return False
```

## 各項目の説明

### 変数について

チェック結果がエラーの場合の出力結果に反映される。
descriptionやtagsは何に使われるか不明。

[*id*]*shortdesc*
(対象ファイルパス):(対象ライン数)
Task/Handler: (モジュールやファイル情報)

以下は出力例

``` command
# ansible-lint -r /vagrant_data/mylint/rules/ test.yml
[CUSTOMRULE3.5.1] Invalid role variable name
/root/playbooks/child.yml:4
Task/Handler: debug msg=called child.yml __file__=/root/playbooks/child.yml __line__=5

[CUSTOMRULE3.5.1] Invalid role variable name
/root/playbooks/roles/role01/tasks/main.yml:1
Task/Handler: debug messag

[CUSTOMRULE3.5.1] Invalid role variable name
/root/playbooks/roles/role01/tasks/main.yml:5
Task/Handler: debug
```

### 関数の実行順序

以下の順で呼び出される。
1. 親プレイブック 
1-1. match()
2-2. matchtasks()
2. 親プレイブックから呼び出された他プレイブックやロール
2−1. match()
2-2. matchtasks()


### match()関数

プレイブックの各行がline変数に格納されて呼び出される。
=プレイブックの行数分match()が呼び出される。

プレイブックが呼び出しす他プレイブックや、ロールに対しても、適用される。

#### Input

**file変数**

対象ファイル情報がdict型で格納されている

| キー名 | 値の例(ルートプレイブック) | 値の例(プレイブック)| 値の例(ロール) |説明|
|:-----------------:|:---:|:---:|:------------------:|:------------------:|
| path | test.yml | /root/playbooks/child.yml | /root/playbooks/roles/role01/tasks/main.yml | チェック対象ファイルのパス |
| type | playbook | playbook | tasks | playbook/tasks |
*patはルートプレイブックだけ相対？


**line変数**

チェック対象行のテキスト情報がunicode型で格納されている

#### Output

チェック結果をbool型で返す。

- True: エラーあり
- False: エラーなし

### matchtasks()関数

プレイブックのタスクがtask変数に格納されて呼び出される。
=プレイブック内のタスク数分のmatchtask()が呼び出される

プレイブックが呼び出しす他プレイブックや、ロールに対しても、適用される。

#### Input

**file変数**

対象ファイル情報がdict型で格納されている

| キー名 | 値の例(ルートプレイブック) | 値の例(プレイブック)| 値の例(ロール) |説明|
|:-----------------:|:---:|:---:|:------------------:|:------------------:|
| path | test.yml | /root/playbooks/child.yml | /root/playbooks/roles/role01/tasks/main.yml | チェック対象ファイルのパス |
| type | playbook | playbook | tasks | playbook/tasks |
*patはルートプレイブックだけ相対？

**task変数**
プレイブックのタスクがdict型で格納される

| キー名 | 値の例(プレイブック) | 値の例(ロール)|説明|
|:-----------------:|:---:|:------------------:|:------------------:|
| delegate_to | None | None | ? |
|name| set_fact simasu | debug message| タスクのnameモジュールの値|
| \_\_file\_\_ | test.yml | /root/playbooks/roles/role01/tasks/main.yml |対象ファイルの絶対パス|
| \_\_line\_\_ | 4 | 1 |対象の行番号|
| \_\_ansible_action_type\_\_ | task | task | Ansibleアクションタイプ？ |
| action | (別表参照) | (別表参照) | モジュール情報が格納されたdict |


**action変数**
モジュールの引数と値がdict型で格納される

| キー名 | 値の例|説明|
|:-----------------:|:------------------:|:------------------:|
| \_\_ansible_module\_\_ | set_fact ||
| my_fact | this is my fact | キーは変数名、値は変数値|
| \_\_file\_\_ | test.yml | |
| \_\_ansible_arguments__|[]|  |
| \_\_line\_\_ | 6 | ファイルの中での対象タスクの最終ライン数 |

#### Output

チェック結果をbool型で返す。

- True: エラーあり
- False: エラーなし