Ansible动态库存脚本-异常行为

问题描述

我正在尝试基于JSON输出为ansible创建基本的动态广告资源脚本。我是jq的新手,但是遇到了一个问题,其中ansible v2.9.14和2.9.15上的动态脚本不喜欢输出,但是如果我将输出发送到文件,然后对其中的输出运行Ansible文件,ansible作品。

这是发生了什么

动态广告资源脚本输出

my_plot <- diamonds_data %>% 
      ggplot() +
      geom_histogram(aes(x = .data[[input$channel1]],fill = .data[[input$color1]]),bins = input$NOofBins) +
      theme_bw()+
      theme(axis.title = element_text(size=26,color="Grey",face="bold"),axis.text = element_text(size=12,face="bold"))+
      labs(x="Diamonds Element",y="Count",title=paste("distribution of diamonds data",input$channel1,sep = " "))

运行和错误

{
  "all": {
      "hosts": {
"ip-172-31-39-30.eu-west-1.compute.internal": null,"ip-172-31-44-224.eu-west-1.compute.internal": null,"ip-172-31-42-6.eu-west-1.compute.internal": null,"ip-172-31-32-68.eu-west-1.compute.internal": null,}
  }
}

现在,如果我将动态脚本输出文件中,然后再次运行ansible,它将起作用:

$ ansible -i ./dynamic1.sh all -m ping -u ubuntu
[WARNING]:  * Failed to parse /home/ubuntu/dynamic1.sh with script plugin: Failed to parse executable inventory script results from /home/ubuntu/dynamic1.sh:
Expecting property name enclosed in double quotes: line 8 column 5 (char 242)
[WARNING]:  * Failed to parse /home/ubuntu/dynamic1.sh with ini plugin: /home/ubuntu/dynamic1.sh:2: Expected key=value host variable assignment,got: {
[WARNING]: Unable to parse /home/ubuntu/dynamic1.sh as an inventory source
[WARNING]: No inventory was parsed,only implicit localhost is available
[WARNING]: provided hosts list is empty,only localhost is available. Note that the implicit localhost does not match 'all'

因此有效...

这是dynamic1.sh的内容。我知道会有更好的方法来做到这一点,但是我只需要基于ansible可以使用的JSON输出中匹配变量的服务器列表。

$ ./dynamic1.sh > output.json

$ cat output.json
{
  "all": {
      "hosts": {
"ip-172-31-39-30.eu-west-1.compute.internal": null,}
  }
}

$ ansible -i output.json all -m ping -u ubuntu
[DEPRECATION WARNING]: distribution Ubuntu 16.04 on host ip-172-31-42-6.eu-west-1.compute.internal should use /usr/bin/python3,but is using /usr/bin/python for
backward compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more @R_693_4045@ion. This feature will be removed in version 2.12. Deprecation
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ip-172-31-42-6.eu-west-1.compute.internal | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },"changed": false,"ping": "pong"
}
ip-172-31-39-30.eu-west-1.compute.internal | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },"ping": "pong"
}
ip-172-31-32-68.eu-west-1.compute.internal | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },"ping": "pong"
}
ip-172-31-44-224.eu-west-1.compute.internal | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },"ping": "pong"
}

有人能帮我解决ansible为什么接受文件而不接受脚本输出的问题吗?

解决方法

Ansible inventory format相反,清单插件script.py期望属性 hosts 列表(例如, hosts: [host1,host2,host3] )不是字典(例如 hosts:{host,host2,host3} )。


广告资源插件yaml.py与主机的字典配合使用

JSON(或YAML,因为JSON是YAML的子集)广告资源工作正常

shell> cat hosts.json
{
    "all": {
        "hosts": {
            "ip-172-31-39-30.eu-west-1.compute.internal","ip-172-31-44-224.eu-west-1.compute.internal","ip-172-31-42-6.eu-west-1.compute.internal","ip-172-31-32-68.eu-west-1.compute.internal"
        }
    }
}
shell> ansible-inventory -i hosts.json --list -vvv
...
Parsed /scratch/tmp/hosts.json inventory source with yaml plugin
{
    "_meta": {
        "hostvars": {}
    },"all": {
        "children": [
            "ungrouped"
        ]
    },"ungrouped": {
        "hosts": [
            "ip-172-31-32-68.eu-west-1.compute.internal","ip-172-31-39-30.eu-west-1.compute.internal","ip-172-31-44-224.eu-west-1.compute.internal"
        ]
    }
}

但是,脚本提供的相同文件将失败

shell> cat hosts.sh 
#!/bin/bash
cat hosts.json
shell> ansible-inventory -i hosts.sh --list -vvv
...
Parsed /scratch/tmp/hosts.sh inventory source with script plugin

[警告]:使用脚本插件无法解析/scratch/tmp/hosts.sh:您 为主机列表定义了一个包含不良数据的组“全部”:{'hosts':{'ip-172-31-39-30.eu- west-1.compute.internal':无,'ip-172-31-44-224.eu-west-1.compute.internal':无, 'ip-172-31-42-6.eu-west-1.compute.internal':无,'ip-172-31-32-68.eu- west-1.compute.internal':无}} ...

{
    "_meta": {
        "hostvars": {}
    },"all": {
        "children": [
            "ungrouped"
        ]
    }
}

广告资源插件script.py与主机列表配合使用

当属性宿主为列表

时,清单插件 script.py 可以正常工作
shell> cat hosts.json
{
    "all": {
        "hosts": [
            "ip-172-31-39-30.eu-west-1.compute.internal","ip-172-31-32-68.eu-west-1.compute.internal"
        ]
    }
}
shell> ansible-inventory -i hosts.sh --list -vvv
...
Parsed /scratch/tmp/hosts.sh inventory source with script plugin
{
    "_meta": {
       ...
    },"ip-172-31-44-224.eu-west-1.compute.internal"
        ]
    }
}

注释

  • 脚本 hosts.sh 的实现不正确,仅用于本示例。引用script.py

说明: -提供的源必须是返回Ansible清单JSON的可执行文件 -源必须接受C(-list)和C(-host)作为参数。 仅当不存在C(_meta)键时才使用C(-host)。