在动态库存脚本中使用库存组变量 [英] Using inventory group variables in dynamic inventory script

查看:34
本文介绍了在动态库存脚本中使用库存组变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题与这个stackoverflow 问题完全一样.我希望我能得到一些不同的答案.一年多来,我一直在努力实现这一目标.但似乎无法实现.

This question is exactly like this stackoverflow question. And I am hoping I get some different answer with this one. I have been trying to achieve this for over a year. but can't seem to achieve it.

精简版的 ansible 目录如下所示:

Stripped down version of my ansible directory looks like this:

[root@python-test ansible]# tree
.
├── files
├── inventory
│   ├── prod
│   │   ├── group_vars
│   │   │   └── all
│   │   └── hosts -> ../../scripts/inventory.py
│   └── staging
│       ├── group_vars
│       │   └── all
│       └── hosts -> ../../scripts/inventory.py
├── roles
│   ├── ant
│   ├── build
│   ├── jdk
│   └── python
├── scripts
│   └── inventory.py
├── templates
└── vars
    └── all.yaml

我想使用一些在 group_vars/all 文件中声明的变量.它有一些我可以在脚本执行期间使用的端点详细信息.此 group_vars/all 的精简版如下所示:

I would like to use some of the variables declared in group_vars/all file. It has some endpoint details that I can use during the script execution. A striped down version of this group_vars/all looks like this:

inv_cloudprovider: aws
inv_environment: prod
inv_environment_type: production
inv_vpc_cidr: 10.0.0.0/16
inv_build_url: 'https://build.{{inv_environment}}.local'
inv_cloud_vpc_name: '{{inv_environment}}-vpc'
inv_vpc_id: '{{inv_environment_type}}-{{inv_cloud_vpc_name}}'
inv_glassfish_version: 4

此时我正在使用 yaml.safe_loads() 加载此文件,然后在脚本执行中使用它们.但问题是存在递归 jinja 模板的变量.我很难让这些变量起作用.所以我想知道我是否可以使用 ansible 为我做这件事.

At this point I am loading this file using yaml.safe_loads() and then using them in script execution. but problem with that is there are variables which are recursive jinja templates. and I am having hard time getting to make those variables work. So I was wondering if I can use ansible to do this for me.

我正在使用 ansible==2.2.3.0python 2.7.

通过这样做,我最接近于在 python 中实现这一点:

The closest I have been to achieving this in python by doing this:

from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager
from ansible.inventory import Inventory

inventory_path = '/root/ansible/inventory/prod/hosts'
inventory = Inventory(DataLoader(), VariableManager(), inventory_path)
group = inventory.get_group('all')
group_vars = group.get_vars()

这可能不是正确的方法,因为我的脚本会尝试自行执行并且递归执行.

Which is probably not the correct way because my script tries to execute itself and that goes on recursively.

是否可以使用 ansible 解析组 vars 变量?如果不是,我如何最好地从该文件中获取变量的最终值?

Is it possible to parse group vars variable using ansible? If no, how do I best get final value of variables from that file?

推荐答案

可以完成这个问题的精简版代码是:

The stripped down version of code that can do what this question asked is:

#!/usr/bin/env python

import json
import os
import sys
import yaml
from jinja2 import Environment

class VarLoader(yaml.SafeLoader):
    @staticmethod
    def construct_python_string(text):
        return str(text.value)

    def yaml_remove_parse(self, text):
        self.construct_python_string(text)

env_name = os.environ.get('ENV_NAME')
script_path = os.path.dirname(os.path.abspath(__file__))
ansible_dir_path = os.path.abspath(script_path + '/../')
global_vars_path = ansible_dir_path + '/vars/all.yaml'
inventory_vars_path = ansible_dir_path + '/inventory/' + env_name + '/group_vars/all'

with open(global_vars_path) as f1, open(inventory_vars_path) as f2:
    global_vars_data = f1.read()
    inventory_vars_data = f2.read()

all_vars_data = global_vars_data + '\n' + inventory_vars_data
VarLoader.add_constructor('tag:yaml.org,2002:float', VarLoader.yaml_remove_parse)
data = yaml.load(all_vars_data, Loader=VarLoader)
jinja_env = Environment()
template_file = jinja_env.from_string(all_vars_data)

for key in data:
    val = data[key]
    if isinstance(val, str) and '{{' in val:
        template = jinja_env.from_string(val)
        data[key] = template.render(**data)

yaml_data = yaml.load(template_file.render(data), Loader=VarLoader)
print(json.dumps(yaml_data))

这适用于 python3 和 python2.输出:

This works with both python3 and python2. Output:

[root@python-test ansible]# python scripts/inventory.py | jq .
{
  "inv_environment": "prod",
  "inv_environment_type": "production",
  "inv_cloudprovider": "aws",
  "gv_redis_port": 6379,
  "inv_glassfish_version": 4,
  "inv_vpc_id": "production-prod-vpc",
  "gv_redis_version": "4.0.11",
  "inv_build_url": "https://build.prod.local",
  "gv_glassfish_admin_user": "admin",
  "inv_vpc_cidr": "10.0.0.0/16",
  "gv_glassfish_asadmin_path": "/usr/local/glassfish/bin/asadmin",
  "gv_java_home": "/usr/local/java/default",
  "inv_cloud_vpc_name": "prod-vpc",
  "gv_tomcat_home": "/usr/local/tomcat",
  "gv_java_path": "/usr/local/java/default/bin/java"
}

这篇关于在动态库存脚本中使用库存组变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆