首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >仅通过Ansible同时更新100个值,一个api调用

仅通过Ansible同时更新100个值,一个api调用
EN

Stack Overflow用户
提问于 2020-01-23 09:00:19
回答 1查看 74关注 0票数 1

我有一个.yml文件,其中包含了一个Axis网络摄像机的数百个配置值。内容如下:

代码语言:javascript
复制
---
axis:
  config:
    "Bandwidth.Limit": 0
    "HTTPS.AllowTLS1": "no"
    "HTTPS.AllowTLS11": "no"
    "HTTPS.AllowSSLV3": "no"
    "HTTPS.Ciphers": AES256-SHA:AES128-SHA
    "HTTPS.Enabled": "yes"
    "HTTPS.Port": 443
    ...

Axis称为Vapix,它提供了一个更新函数来更新一个值,因此我在这些值中圈了一个圈,并在每次迭代中触发了一个新的API调用:

代码语言:javascript
复制
---
  - name: update parameters
    local_action:
      module: uri 
      user: "{{ axis_snmp_role.login_user }}"
      password: "{{ axis_snmp_role.login_password }}"
      url: "{{ axis_snmp_role.server_url }}?action=update&{{ item.key }}={{ item.value }}"
      validate_certs: false
    with_dict: "{{ axis.config }}"

事实证明这是可行的,但要花上很长时间。我手动发现,可以使用一个API调用更新多个值,方法是将键/值对与&-符号粘在一起,如下所示:

代码语言:javascript
复制
https://{{ axis_snmp_role.server_url }}/axis-cgi/param.cgi?action=update&ImageSource.I0.Sensor.ExposureValue=100&Image.I0.Appearance.Compression=50

所以我用它来执行一个很大的API调用,它将同时设置所有的值。

代码语言:javascript
复制
---
  - name: Create parameter list
    set_fact:
      my_parameters: "{{ my_parameters | default([]) + [item.key + '=' + item.value|string|urlencode() ] }}"
    with_dict: "{{ axis.config }}"

  - name: update parameters
    #no_log: true
    local_action:
      module: uri 
      user: "{{ axis_snmp_role.login_user }}"
      password: "{{ axis_snmp_role.login_password }}"
      url: "{{ axis_snmp_role.server_url }}?action=update&{{ my_parameters | join('&') }}"
      validate_certs: false
    #with_dict: "{{ axis.config }}"

原来网络摄像头不喜欢一次得到这么多的值,所以我想我不得不把这个过程分割一下。

是否有可能创建一个Ansible循环,同时读取100个键/值对,创建一个包含所有参数的大api调用,将其发送出去并重复执行,直到达到配置文件的末尾?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-23 12:25:27

Q:“是否有可能一次创建一个读取100个键/值对的Ansible循环,与它们一起创建一个很大的API调用,然后将其发送出去并重复到配置文件的末尾?”

答:是的。这是可能的。下面是关于如何拆分参数的过程。将变量period设置为100并对其进行测试。

给定axis.config声明用于测试的period

代码语言:javascript
复制
  vars:
    axis:
      config:
        "Bandwidth.Limit": 0
        "HTTPS.AllowTLS1": "no"
        "HTTPS.AllowTLS11": "no"
        "HTTPS.AllowSSLV3": "no"
        "HTTPS.Ciphers": AES256-SHA:AES128-SHA
        "HTTPS.Enabled": "yes"
        "HTTPS.Port": 443
    period: 2

创建一个参数列表并计算列表的长度

代码语言:javascript
复制
    - set_fact:
        config_list: "{{ config_list|default([]) + [item.key ~ '=' ~ item.value] }}"
      loop: "{{ axis.config|dict2items }}"
    - debug:
        var: config_list
    - set_fact:
        config_length: "{{ config_list|length }}"
    - debug:
        var: config_length

代码语言:javascript
复制
    "config_list": [
        "HTTPS.Ciphers=AES256-SHA:AES128-SHA", 
        "HTTPS.AllowTLS11=no", 
        "HTTPS.AllowTLS1=no", 
        "HTTPS.Enabled=yes", 
        "HTTPS.Port=443", 
        "Bandwidth.Limit=0", 
        "HTTPS.AllowSSLV3=no"
    ]


    "config_length": "7"

config_list拆分为长度period的子列表

代码语言:javascript
复制
    - set_fact:
        split_list: "{{ split_list|default([]) +
                        [config_list[split0|int:split1|int]] }}"
      vars:
        split0: "{{ ansible_loop.previtem|default(0) }}"
        split1: "{{ ansible_loop.last|ternary(config_length, item) }}"
      loop: "{{ range(period, config_length|int, period)|list }}"
      loop_control:
        extended: yes
    - debug:
        var: split_list

给出

代码语言:javascript
复制
    "split_list": [
        [
            "HTTPS.Ciphers=AES256-SHA:AES128-SHA", 
            "HTTPS.AllowTLS11=no"
        ], 
        [
            "HTTPS.AllowTLS1=no", 
            "HTTPS.Enabled=yes"
        ], 
        [
            "HTTPS.Port=443", 
            "Bandwidth.Limit=0", 
            "HTTPS.AllowSSLV3=no"
        ]
    ]

循环列表并加入参数

代码语言:javascript
复制
    - debug:
        msg: "{{ item|join('&') }}"
      loop: "{{ split_list }}"

给出

代码语言:javascript
复制
    "msg": "HTTPS.Ciphers=AES256-SHA:AES128-SHA&HTTPS.AllowTLS11=no"
    "msg": "HTTPS.AllowTLS1=no&HTTPS.Enabled=yes"
    "msg": "HTTPS.Port=443&Bandwidth.Limit=0&HTTPS.AllowSSLV3=no"

使用一些自定义过滤器(下面),将简化该过程。

代码语言:javascript
复制
$ cat filter_plugins/dict_filters.py
def dict2list(d):
    l = []
    for i in d:
        h = {i:d[i]}
        l.append(h)
    return l

class FilterModule(object):

    def filters(self):
        return {
            'dict2list' : dict2list
            }

$ cat filter_plugins/list_filters.py
def list_split(l, p):
    split_list = []
    for i in range(p, len(l)+p, p):
        if i == p:
            split_list.append(l[0:p])
        elif i > len(l):
            split_list.append(l[j:])
        else:
            split_list.append(l[j:i])
        j = i
    return split_list

class FilterModule(object):

    def filters(self):
        return {
            'list_split' : list_split
            }

$ cat filter_plugins/hash_filters.py
def hash_to_tuple(h):
    return h.items()[0]

class FilterModule(object):

    def filters(self):
        return {
            'hash_to_tuple': hash_to_tuple
            }

以下任务

代码语言:javascript
复制
    - set_fact:
        config_list: "{{ axis.config|
                         dict2list|
                         map('hash_to_tuple')|
                         map('join', '=')|
                         list }}"

    - set_fact:
        split_list: "{{ config_list|list_split(period) }}"

    - debug:
        msg: "{{ item|join('&') }}"
      loop: "{{ split_list }}"

给同样的结果

代码语言:javascript
复制
    "msg": "HTTPS.Ciphers=AES256-SHA:AES128-SHA&HTTPS.AllowTLS11=no"
    "msg": "HTTPS.AllowTLS1=no&HTTPS.Enabled=yes"
    "msg": "HTTPS.Port=443&Bandwidth.Limit=0"
    "msg": "HTTPS.AllowSSLV3=no"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59874706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档