Ansible 是一个顶级的开源项目,表面上,它提供了一种简单的方法来标准化您现有的自动化,并允许它在多个主机上并行运行,并且它非常成功地做到了这一点。然而,实际上,Ansible 有能力扩展您现有自动化所做的事情,以整合其他系统,并真正简化您日常例行工作各个方面的任务。
这种能力始于 Ansible 中包含的 collections 和 roles 以及通过 Ansible Galaxy 分发的所有第三方实用程序。您可能已经使用 Web 浏览器或 curl 查询过 API,但 Ansible 被忽视的一个能力是它能够很好地利用 API 作为任何 playbook 的一部分。 这非常有用,因为内部和全球互联网上构建和部署的 REST API 的数量呈指数级增长。 甚至有一个 public-apis GitHub 仓库 列出了数百个免费 API,涵盖十几个类别,以供参考。
一个基本的 API playbook
实际上,这归结为 Ansible 中的一些关键核心功能,这些功能通过一个特定的内置任务 _uri_ 很好地公开。 在这篇文章中,我将通过一个相当简单的例子来说明如何调用 REST API,并使用该调用的数据来决定下一步该做什么。 这适用于 Ansible 2.9 及更高版本。 在更高版本(特别是 v4)中,我们使用的模块需要加上 _ansible.builtin_ 前缀,例如 _ansible.builtin.set_fact_ 而不是仅 _set_fact_。
要开始使用,您需要一个基本的 playbook 来构建。 在本例中,您只使用本地调用,因此不需要超级用户权限。
首先,创建这个 YAML 文件来建立一个工作基线
---
- name: Using a REST API
become: false
hosts: localhost
gather_facts: false
tasks:
- debug:
msg: “Let’s call an API”
这是运行后的输出
% ansible-playbook using-a-rest-api.yml
PLAY [Using a REST API] *********************************************************************************************
TASK [debug] ********************************************************************************************************
ok: [localhost] => {
"msg": "“Let’s call an API”"
}
PLAY RECAP **********************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
调用 API
要调用实际的 API,您可以使用 _uri_ 模块。 这里有两个例子。 第一个是 GET 请求,第二个是带有参数的 POST 请求,以显示不同的可用选项。
---
- name: Everyone loves a good Chuck Norris joke
uri:
url: https://api.chucknorris.io/jokes/random
method: GET
- name: Login to an API
uri:
url: https://auth.example.com/oauth/access_token
method: POST
body_format: json
body:
name: your_username
password: your_password
client_id: YOUR_CLIENT_ID
access_token: ACCESS_TOKEN
connection: CONNECTION
scope: SCOPE
我使用第一个 API 用于本文的其余部分,以展示如何使用返回的数据。 问题是,您如何收集返回的数据,以及它的外观是什么?
[ 提升您的自动化专业知识。 获取 Ansible 清单: 迁移到 Red Hat Ansible Automation Platform 2 的 5 个理由 ]
要收集在 Ansible 中运行的任何任务的输出,您可以使用 _register_ 属性,然后您可以使用 _debug_ 任务来显示原始数据。 在使用 _uri_ 调用的 API 的情况下,所有输出都放在结果的 .json. Subsection 下。 _uri_ 命令和其他输出也位于该顶层。 这些可用于通过查看状态等其他数据字段来确保 API 调用有效。
这是您必须添加到原始 playbook 中的两个任务,以便将 API 调用添加到混合中,以便稍后执行某些操作。
- name: Getting the definition of awesome
uri:
url: https://api.chucknorris.io/jokes/random
method: GET
register: results
- debug:
var: results
运行它以查看 debug 生成的输出
TASK [debug] ********************************************************************************************************
ok: [localhost] => {
"results": {
"alt_svc": "h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400, h3-28=\":443\"; ma=86400, h3-27=\":443\"; ma=86400",
"cf_cache_status": "DYNAMIC",
"cf_ray": "694f7d791aeb19e7-EWR",
"changed": false,
"connection": "close",
"content_type": "application/json;charset=UTF-8",
"cookies": {},
"cookies_string": "",
"date": "Sun, 26 Sep 2021 21:12:23 GMT",
"elapsed": 0,
"expect_ct": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"",
"failed": false,
"json": {
"categories": [],
"created_at": "2020-01-05 13:42:26.991637",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "IjqNNWKvSDeVKaI82PaT1g",
"updated_at": "2020-01-05 13:42:26.991637",
"url": "https://api.chucknorris.io/jokes/IjqNNWKvSDeVKaI82PaT1g",
"value": "One person stated that Chuck Norris has forgotten more about killing than anyone will ever know. That is not true -- Chuck Norris never forgets. Ever."
},
"msg": "OK (unknown bytes)",
"nel": "{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}",
"redirected": false,
"report_to": "{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=HVPJYMVr%2B3wB1HSlgxv6GThBMjkBJgfdu0DPw%2BunjQzQ9YfXZqifggIJ%2FxOIKgOu6JP1SrPsx1jCCp3GQ9hZAp7NO0pmlTZ0y3ufbASGwLmCOV1zyaecUkSwQD%2Fv3RYYgZTkaSQ%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}",
"server": "cloudflare",
"status": 200,
"transfer_encoding": "chunked",
"url": "https://api.chucknorris.io/jokes/random",
"via": "1.1 vegur"
}
}
现在您可以看到所有输出,创建一个自定义消息,列出 API 返回的值。 这是完整的 playbook
---
- name: Using a REST API
become: false
hosts: localhost
gather_facts: false
tasks:
- debug:
msg: “Let’s call an API”
- name: Everyone loves a good Chuck Norris joke
uri:
url: https://api.chucknorris.io/jokes/random
method: GET
register: results
- debug:
var: results.json.value
现在是完整的输出
PLAY [Using a REST API] *********************************************************************************************
TASK [debug] ********************************************************************************************************
ok: [localhost] => {
"msg": "“Let’s call an API”"
}
TASK [Everyone loves a good Chuck Norris joke] **********************************************************************
ok: [localhost]
TASK [debug] ********************************************************************************************************
ok: [localhost] => {
"results.json.value": "Chuck Norris is the only computer system that beats a Mac or a PC. Too bad all it does is round house kicks the user."
}
PLAY RECAP **********************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
下一步
事情可能会比我这里展示的复杂得多。 要获得更多详细信息,请前往 Ansible 的 文档。
评论已关闭。