我试着通过Ansible Tower的API传递变量给模板并执行

在通过Ansible Tower的API执行模板时,我遇到了一些困难,需要传递变量(extra_vars),现将解决方法记录下来。

环境

項目バージョンOSRHEL7.4Ansible Tower3.2.3python3.4

Ansible Tower API文档

请点击此链接查看《Ansible Tower API文档》中3.1.4版本的HTML页面。

验证故事

    • Playbookはローカルの /var/lib/aws/projects に直接作成したものを使います

 

    • REST APIから変数をセットした情報を渡してテンプレートを実行します

 

    APIはpythonスクリプトから実行します

Ansible Tower的设置

项目设定

スクリーンショット 2018-03-20 22.08.40.png

模板设置

请注意,在启动提示中勾选上追加变量的选项。
如果没有勾选,则通过API传递变量也会被忽视。(默认情况下被忽视)

スクリーンショット 2018-03-20 22.09.39.png

测试用的Playbook

我們將使用以下兩個範本進行測試。

通过msg输出变量值。

---
- name: TEST Playbook
  hosts: localhost
  tasks:
    - debug: msg="{{ MSG }}"

使用循环输出变量的值。

---
- name: TEST Playbook
  hosts: localhost
  tasks:
    - debug:
        msg: "{{ item }}"
      with_items: "{{ str_list }}"

执行API的工具

原文:ソース

中文翻译:酱料

作为验证工具,我们将使用以下内容。

#!/usr/bin/env python3
from getpass import getpass
import argparse
import sys
import json
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

def options():
    parser = argparse.ArgumentParser(prog="ansible-tower-api-tool.py",
                                     add_help=True,
                                     description="Ansible Towerのテンプレートを実行するツール")
    parser.add_argument("--host",
                        type=str, required=True,
                        help="Ansible TowerサーバのIPまたはホスト名")
    parser.add_argument("--username", "-u",
                        type=str,default="admin",
                        help="Ansible Towerアカウント(default:admin)")
    parser.add_argument("--password", "-p",
                        type=str,
                        help="Ansible Towerアカウントのパスワード")
    parser.add_argument("--template", "-t",
                        type=str, required=True,
                        help="実行するテンプレート名")
    parser.add_argument("--data", "-d",
                        type=eval,
                        help="テンプレートのextra_vars")

    args = parser.parse_args()
    if(not(args.password)):
        args.password = getpass(prompt="Ansible Tower Password: ")

    return args

def get_header():
    headers = { "Content-Type": "application/json" }
    return headers

def get_cred(username, password):
    cred = {
        'username': username,
        'password': password
    }
    return cred

def create_url(host, path):
    url = "https://%s%s" % (host, path)
    return url

def get_token(host, cred):
    url = create_url(host, "/api/v2/authtoken/")
    r = post(url, get_header(), cred)

    if(r.status_code == 200):
        token = json.loads(r.text)['token']
        return token
    else:
        print('Token acquisition error.')
        sys.exit(1)

def get(url, headers):
    r = requests.get(url,
                     headers=headers,
                     verify=False)

    return r

def post(url, headers, data):
    r = requests.post(url,
                      headers=headers,
                      data=json.dumps(data),
                      verify=False)

    return r

if __name__ == '__main__':
    # オプションを取得
    args = options()

    # 認証Tokenを取得
    cred = get_cred(args.username, args.password)
    token = get_token(args.host, cred)

    # ヘッダー情報を生成
    headers = get_header()
    headers["Authorization"] = "Token " + token

    # テンプレードID取得
    url = create_url(args.host, "/api/v1/job_templates")
    r = get(url, headers)

    for i in json.loads(r.text)['results']:
        if(i["name"] == args.template):
            template_launch_url = i["related"]["launch"]
            break

    if(not("template_launch_url" in locals())):
        print("%s template not found" % args.template)
        sys.exit(1)

    # テンプレートを実行
    url = create_url(args.host, template_launch_url)
    r = post(url, headers, args.data)
    print(r.status_code)

用法

$ ./ansible-tower-api-tool.py --host AnsibleTowerのIP -t テンプレート名 -d key,valueをセットしたdict

审查

尝试将值存入MSG变量。

我会将 “TEST Message” 放入 MSG 中,并尝试执行API。

$ ./ansible-tower-api-tool.py --host 192.168.0.234 -t TEST -d '{"extra_vars": {"MSG":"TEST Message"}}'
Ansible Tower Password:
201
スクリーンショット 2018-03-20 22.30.13.png

尝试在循环中执行

我会将 Mes1、Mes2 和 Mes3 放入 str_list 数组中,然后尝试执行 API。

$ ./ansible-tower-api-tool.py --host 192.168.0.234 -t TEST -d '{"extra_vars": {"str_list":["Mes1","Mes2","Mes3"]}}'
Ansible Tower Password:
201
スクリーンショット 2018-03-20 22.34.52.png

简单说就是”总结”。

如果通过Ansible Tower的API传递变量,请确保在”Additional Variables”的启动提示处已经被选中。可以通过API(以下URL)进行确认。

URLhttps://$ansible_tower_ip/api/v1/job_templates/$TemplateID/launch/

以下是GET请求的结果示例。
需要将ask_variables_on_launch设置为true。

{
  "can_start_without_user_input": false,
  "passwords_needed_to_start": [],
  "ask_variables_on_launch": true,
  "ask_tags_on_launch": false,
  "ask_diff_mode_on_launch": false,
  "ask_skip_tags_on_launch": false,
  "ask_job_type_on_launch": false,
  "ask_limit_on_launch": false,
  "ask_verbosity_on_launch": false,
  "ask_inventory_on_launch": false,
  "ask_credential_on_launch": false,
  "survey_enabled": false,
  "variables_needed_to_start": [],
  "credential_needed_to_start": false,
  "inventory_needed_to_start": false,
  "job_template_data": {
    "id": 13,
    "description": "",
    "name": "TEST"
  },
  "defaults": {
    "credential": {
      "id": 2,
      "name": "root"
    },
    "job_tags": "",
    "extra_vars": "",
    "verbosity": 0,
    "job_type": "run",
    "diff_mode": false,
    "skip_tags": "",
    "limit": "",
    "inventory": {
      "id": 2,
      "name": "TEST Host List"
    },
    "vault_credential": {
      "id": null,
      "name": null
    }
  }
}
广告
将在 10 秒后关闭
bannerAds