zoukankan      html  css  js  c++  java
  • AnsibleUndefinedVariable: 'unicode object' has no attribute u'xxx'

    Ansible通过jinja2模块对后缀为.j2的文件进行jinja模板渲染,某一次在引用一个类似python dict的配置文件变量时报出了如上错误。

    这里直接参考一个ansible github issue中的示例进行解释:

    "AnsibleUndefinedVariable: 'unicode object' has no attribute when dict in json format · Issue #19356 · ansible/ansible (github.com)

    ansible配置文件中有如下一个变量:

    [nginx:vars]
    nginx_upstream_check_upstreams={ "yAuthAPI": { "enable": true, "http_send": "GET / HTTP/1.0\r\n\r\n", "expect_alive": "http_2xx" }, "yAuthServer": { "enable": true, "http_send": "GET / HTTP/1.0\r\n\r\n", "expect_alive": "http_2xx" }}

    上述配置中,变量名为nginx_upstream_check_upstreams,变量的值是json格式的。

    作者引用上述变量的jinja模板为:

    {% for backend in nginx_backends %}
    upstream {{ backend }} {
        ip_hash;
    {% for host in nginx_backends[backend] %}
        server {{ host }};
    {% endfor %}
    
    {% if nginx_upstream_check_enable %}
    {% if nginx_upstream_check_upstreams[backend].enable %}
        check interval=5000 rise=1 fall=3 timeout=4000 type=http;
        check_http_send "{{ nginx_upstream_check_upstreams[backend].http_send }}";
        check_http_expect_alive {{ nginx_upstream_check_upstreams[backend].expect_alive }};
    {% endif %}
    {% endif %}
    }

    报错为:

    fatal: [10.2.79.1]: FAILED! => {"changed": false, "failed": true, "msg": "AnsibleUndefinedVariable: 'unicode object' has no attribute u'yAuthAPI'"}

    模板中的其他地方忽略,只要注意其中的nginx_upstream_check_upstreams[backend],这里就是出错的地方。

    报错提示的比较明显,就是出现了一个ansible未定义的变量,其类型为unicode object,且其没有yAuthAPI的属性。
    这说明ansible把nginx_upstream_check_upstreams这个变量当成了一个unicode解析,这显然不符合预期,我们希望ansible将其当做一个dict进行解析。
    仔细看下nginx_upstream_check_upstreams的值发现: "enable": true,这里显然有问题,python中的bool类型True才是合法值,这里的true未首字母大写,所以ansible解析时只能将其当做一个字符类型。
    解决办法就是将上述true改为True,这才是合法的python bool值,才可以被jinja2模块解析。
     
    我自己遇到的问题:
    与上述问题类似,也是在引用一个json格式的变量时出错,只不过我是其中有一段类似 "enable": null。在python中none才是合法的值。
    之所以生成的是null是因为配置文件是使用基于java的freemarker模板进行渲染的。
     
    总结:
    在ansible的j2文件中渲染jinja模板时,如果使用了json格式的变量,且想要将其当做一个python dict引用,那么就需要验证好json的格式,确保其可以正确的使用python语言解析,类似true,null这种字符需要使用True,None代替,或者使用其他方法变通。
    一种简单的验证方式为,使用python/ipython命令行将对应的json值直接赋给一个python变量,如果正常说明符合python的dict格式,否则不合法。
    想建一个数据库技术和编程技术的交流群,用于磨炼提升技术能力,目前主要专注于Golang和Python以及TiDB,MySQL数据库,群号:231338927,建群日期:2019.04.26,截止2021.02.01人数:300人 ... 如发现博客错误,可直接留言指正,感谢。
  • 相关阅读:
    centos 7 有点意思
    Thinkphp中路由Url获取的使用方法
    smarty中的母板极制_extends和block标签
    linux下php多版本的并存实现
    centos nginx,php添加到Service
    CI_Autocomplete_2.0.php轻松实现Bebeans与Codeigniter的智能提示
    php中的性能挖掘
    tar命令,转来等用
    Smarty插件简单开发
    iOS 7用户界面过渡指南
  • 原文地址:https://www.cnblogs.com/leohahah/p/14436630.html
Copyright © 2011-2022 走看看