json - 在 Ansible 中检索、操作和发回 JSON
问题描述
我们必须为交换机设置和取消设置 VLAN 配置。幸运的是,Unify Controller 提供了一个 API,它通常与 Ansible 一起使用。
但是,使用 API 更改单个元素是不可能的,Ansible 必须获取当前配置,找到并更改所需的元素并发回配置。(我推动了所需的配置更改。这导致交换机除了我的配置更改之外什么都没有,我觉得像 Facebook 的人......)
---
- hosts: adm01.local
gather_facts: false
tasks:
- name: Use vars from Vault
include_vars: unifi_info.yaml
- name: Get Cookie from Unifi
uri:
url: https://{{ url }}/api/login
method: POST
body_format: json
body: {"username":"{{ username }}","password":"{{ password }}"}
validate_certs: false
register: login
- name: Print returned data to ensure it worked
debug:
msg: "{{ login }}"
- name: Get current config
uri:
url: https://{{ url }}/api/s/default/stat/device/
method: GET
body_format: json
headers:
Cookie: "{{ login.cookies_string }}"
validate_certs: false
register: switchConf
- name: Print SwitchConf
debug:
msg: "{{ switchConf }}"
- name: Set port 2 to CLIENTVLAN
uri:
url: https://{{ url }}/api/s/default/rest/device/60acc79964542d80774123b5/
method: PUT
body_format: json
# DISABLE VLAN: "60aca5ee64542d807741239d"
# CLIENTVLAN: ""60accb9b64542d80774123d1"
#body: {"port_overrides": [{"port_idx": 2, "portconf_id":"60accb9b64542d80774123d1"}]}
headers:
Cookie: "{{ login.cookies_string }}"
validate_certs: false
register: portConf
- name: Print portConf
debug:
msg: "{{ portConf }}"
SwitchConf 打印(仅相关部分):
"msg": {
"access_control_allow_credentials": "true",
"access_control_expose_headers": "Access-Control-Allow-Origin,Access-Control-Allow-Credentials",
"changed": false,
"connection": "close",
"content_type": "application/json;charset=UTF-8",
"cookies": {},
"cookies_string": "",
"date": "Wed, 20 Oct 2021 18:22:24 GMT",
"elapsed": 0,
"failed": false,
"json": {
"data": [
{
(...)
"port_overrides": [
{
"port_idx": 1,
"portconf_id": "A"
},
{
"port_idx": 2,
"portconf_id": "B"
},
{
"port_idx": 3,
"portconf_id": "B"
},
{
"port_idx": 5,
"portconf_id": "B"
},
{
"port_idx": 6,
"portconf_id": "B"
},
{
"port_idx": 7,
"portconf_id": "B"
},
(...)
],
(...)
}
]
},
"msg": "OK (unknown bytes)",
"redirected": false,
"status": 200,
"transfer_encoding": "chunked",
"url": "https://adm01.local:8443/api/s/default/stat/device/",
"vary": "accept-encoding,origin,accept-encoding",
"x_frame_options": "DENY"
}
}
所以,问题是:如何使用 Ansible 获取 JSON 数据报 portConf->data->port_overrides 并将“portconf_id”更改为“X”,“port_idx”==2,以便使用 post_overrides 对其进行 POST背部?
解决方案
YAML 中的字典是不可变的。你必须创建一个新的来改变任何东西。鉴于简化数据
portConf:
status: 200
json:
data:
- port_overrides:
- port_idx: 1
portconf_id: A
- port_idx: 2
portconf_id: B
- port_idx: 3
portconf_id: C
以及所需的更改
diff:
port_idx: 2
portconf_id: X
下面的任务对json.data进行了更改
- set_fact:
_json: "{{ {'data': [{'port_overrides': _port_change}]} }}"
vars:
_port_remove: "{{ portConf.json.data.0.port_overrides|
rejectattr('port_idx', 'eq', diff.port_idx)|
list }}"
_port_change: "{{ (_port_remove + [diff])|sort(attribute='port_idx') }}"
给
_json:
data:
- port_overrides:
- port_idx: 1
portconf_id: A
- port_idx: 2
portconf_id: X
- port_idx: 3
portconf_id: C
下一个任务结合了这些变化
- set_fact:
portConf: "{{ portConf|combine({'json': _json}) }}"
给
portConf:
json:
data:
- port_overrides:
- port_idx: 1
portconf_id: A
- port_idx: 2
portconf_id: X
- port_idx: 3
portconf_id: C
status: 200
推荐阅读
- python-3.x - 使用jupyter在熊猫中应用过滤器,但没有记录只有标题显示
- c# - 创建表达式
从带有重载构造函数的方法名 - python - 为什么当 Python Sklearn 中的列大于行时它会起作用(线性回归)
- sql - 如果目标表具有 GENERATE ALWAYS AS IDENTITY COLUMN,Oracle 是否允许 SQL INSERT INTO 对 VALUES 使用 SELECT 语句
- sql - 如何使用 case 语句在 sql 中返回不同的 pull?
- c# - c# 进度条在第二次运行时从旧值开始
- bash - 在 Ubuntu 中转换音频文件的采样率的脚本
- python - pastebin api:无效的 api_dev_key
- javascript - ReactJS:为什么可以将函数传递给 setState() 来触发同步更新?
- java - 在文件路径前加上“..\”有什么作用?