ansible-api分析(VariableManager变量)

一. 简述:

ansible是一个非常强大的工具,可以支持多种类型(字符,数字,列表,字典等)的变量。除了有大量的内置变量及fact变量,也可以通过多种方式进行变量自定义 。不同方式定义的变量,优先级也不太一样,之前有写过变量定义的说明,这里,从在使用api的过程中说明下。

二. VariableManager变量详解与使用案例

如果了解/使用过python 2.0版本以上的同学, 应该不会陌生以下几个类:

from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager 
from ansible.inventory import Inventory
from ansible.playbook.play import Play 
from ansible.executor.task_queue_manager import TaskQueueManager  
from ansible.plugins.callback import CallbackBase    

  其中VariableManager是用来存储各类的变量信息的。大家都知道,ansible可以分别通过yaml配置文件中的var,命令行的方式进行变量定义,hosts文件,也可以通过register(task内部专递),交互式的定义。 其实,还可以在一些比较特殊的场景进行变量定义。比如,我们动态生成hosts时(inventory),也可以定义。当然,在走api时,也可以通过这里要说的,VariableManager模块定义。

案例 (抛砖引玉): 

    通常情况下,我们可能会把变量定义在hosts文件,或者var下, 但在有些特殊的环境下,其实并不能满足我们的需求。比如,我司有aws,ali,ten等多个云运营商,同时,我们还会使用不同的系统版本(如centos6、fedora7)在在这个环境系下,我们不希望在初始化时,不同的商家/版本,使用不同的初始化脚本(playbook )【如果单独使用,意味着我们需要维护至少6个,三个运营商的提供环境是有差异性的, 当然,我们也考虑过基于某一个运营商的系统,打镜像,然后上传至其他运行商,实现环境统一的情况,但我们不能保证,这样操作会不会跟云平台能够完全契合】。所以,对于这种环境,我们需要设计一个统一的操作script,动态获取系统所属版本,所在运营商。include对应的配合文件,进行初始化工作。

结构如下:

# tree roles/ -d
initial_system.yaml 
roles/
├── initial_system_6
│   ├── files
│   ├── handlers
│   ├── tasks
│   │   ├── disk_initial.yaml
│   │   ├── file_copy.yaml
│   │   ├── jenkins_node.yaml
│   │   ├── main_ten.yaml
│   │   ├── main_ali.yaml
│   │   ├── main_aws.yaml
│   │   ├── main.yaml
│   │   ├── mysql_master.yaml
│   │   ├── mysql_slave.yaml
│   │   ├── nginx.yaml
│   │   ├── nodejs.yaml
│   │   ├── package_install.yaml
│   │   ├── py35.yaml
│   │   └── tomcat.yaml
│   ├── templates
│   └── vars
├── initial_system_7
│   ├── files
│   ├── handlers
│   ├── tasks
│   │   ├── disk_initial.yaml
│   │   ├── file_copy.yaml
│   │   ├── jenkins_node.yaml
│   │   ├── main_ten.yaml
│   │   ├── main_ali.yaml
│   │   ├── main_aws.yaml
│   │   ├── main.yaml
│   │   ├── mysql_master.yaml
│   │   ├── mysql_slave.yaml
│   │   ├── nginx.yaml
│   │   ├── nodejs.yaml
│   │   ├── package_install.yaml
│   │   ├── py35.yaml
│   │   └── tomcat.yaml
│   ├── templates
│   └── vars

如上图,我需要根据系统版本号,include对应的系统版本role(initial_system_6/7)。然后加载对应的task/main.yaml, 再根据获取的idc/运营商,加载不同的配置文件(main_aws.yaml)

我的playbook主配置内容如下:

# cat initial_system.yaml 
---
- hosts: "{{ host_name }}"remote_user: ansiblebecome: yesserial: 5gather_facts: noroles:- initial_system_{{ system_versions }}

在这种情况下,我们是不能通过hosts/(inventory)来定义system_versions(系统版本)变量的,因为它在执行时roles时,还未获取到对应的变量, 这种情况下,如果不走api(源码入手),我们只能通过命令(ansible-playbook -e)的方式进行传递。 由于我们采用了api, 所以,我们可以通过上文中的VariableManager模块进行变量定义。

代码片段如下:

。。。。。。。。。。。。。。。。
class vipkidplayexecutor(PlaybookExecutor):def __init__(self,playbooks,inventory,variable_manager,loader,options,passwords,stdout_callback=None):self._playbooks = playbooksself._inventory = inventoryself._variable_manager = variable_managerself._loader = loaderself._options = optionsself.passwords = passwordsself._unreachable_hosts = dict()if options.listhosts or options.listtasks or options.listtags or options.syntax:self._tqm = Noneelse:self._tqm = TaskQueueManager(inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=self.passwords, stdout_callback=stdout_callback)check_for_controlpersist(C.ANSIBLE_SSH_EXECUTABLE)class Playbookjob(object):def __init__(self,playbooks,host_list,host_name,support_service=[],ssh_user='ansiblle',passwords=None,forks=5):self.playbooks = playbooksself.host_list = host_listself.ssh_user = ssh_userself.passwords = dict(vault_pass=passwords)self.forks = forksself.host_variable = {'host_name':host_name,'support_service':support_service}self.variable_manager = VariableManager()self.variable_manager.extra_vars =  dict(data_obtain(host_name),**self.host_variable)print(self.variable_manager.extra_vars)self.loader = DataLoader()self.Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user','remote_user', 'check', 'sudo_user', 'sudo','listhosts','listtasks','listtags','syntax'])self.options = self.Options(connection='smart', module_path=None, forks=self.forks, become=True, become_method='sudo', become_user='root',remote_user=self.ssh_user, check=False,sudo_user=None,sudo='yes',listhosts=None,listtasks=None,listtags=None,syntax=None)self.results_callback = CallbackModule()#host_list produceinev_data = open(self.host_list,'r').read()inev_file = '#!/usr/bin/python\nhost_info={"all":{"hosts":%s}}\n%s' % (host_name.split(','),inev_data)self.hostsFile = NamedTemporaryFile(delete=False)self.hostsFile.write(inev_file)self.hostsFile.close()self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=self.hostsFile.name)#        print('-----%s' %self.host_list)
#        self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=self.host_list)self.variable_manager.set_inventory(self.inventory)def run(self):playbook_control = vipkidplayexecutor(playbooks = self.playbooks,inventory = self.inventory,variable_manager = self.variable_manager,loader = self.loader,options = self.options,passwords = self.passwords,stdout_callback = self.results_callback)playbook_control.run()。。。。。。。。。。。。。。。。

先定义类self.variable_manager = VariableManager()

然后添加变量脚本传入变量: {'host_name':host_name,'support_service':support_service}

然后将变量加载至variable_manager的extra_vars方法,然后交给api(vipkidPlaybookExecutor)操作。

存储的变量(extra_vars)其实就是一个字典(dict), 代码中引入了变量和data_obtain方法的结果,可解析为:

{'host_name': 'l-ansible-initial1.ops.prod.aws.dm', 'system_versions': 6, 'b': 'c', 'support_service': ['tomcat','nginx']}

传入要初始化的主机(host_name),系统版本(system_versions),部署的服务(tomcat,nginx)。

然后通过TaskQueueManager将变量传递到Task。

 感兴趣或有相关需求的同学,可以根据实际情况适配。

 ----------------------------------------------------------------------------------------------

深耕运维行业多年,擅长linux、容器云原生、运维自动化等方面。
承接各类运维环境部署、方案设计/实施、服务代运维工作,欢迎沟通交流 !

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/66541.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 界面外观

一、前言 1、 一个完善的应用程序,不仅应该有实用的功能,还要有一个漂亮的外观,这样才能使应用程序更加友好,更加吸引用户。 2、 作为一个跨平台的UI开发框架,Qt提供了强大而灵活的界面外观设计机制。 3、 本篇会讲解&…

【Uniapp-Vue3】image媒体组件属性

如果我们想要在页面上展示图片就需要使用到image标签。 这部分最重要的是图片的裁剪,图片的裁剪和缩放属性: mode 图片裁剪、缩放的模式 默认值是scaleToFill 我将用两张图片对属性进行演示,一张是pic1.jpg(宽更长&#xf…

VisionPro软件Image Stitch拼接算法

2D图像拼接的3种情景 1.一只相机取像位置固定,或者多只相机固定位置拍图,硬拷贝拼图,采用CopyRegion工具实现 2.一只或多只相机在多个位置拍照,相机视野互相重叠,基于Patmax特征定位后,无缝 拼图&#xff…

“多维像素”多模态雷视融合技术构建自动驾驶超级感知能力|上海昱感微电子创始人蒋宏GADS演讲预告

2025年1月14日,第四届全球自动驾驶峰会将在北京中关村国家自主创新示范区展示交易中心-会议中心举行。经过三年的发展,全球自动驾驶峰会已经成长为国内自动驾驶领域最具影响力、规模最大的产业峰会之一。在主会场下午的城市NOA专题论坛上,上海…

python:装饰器函数 timer

python 装饰器本身就是一个函数,它的作用是装饰一个其他的函数,但是不改变原有的程序功能,还能增添新的功能,调用函数时用timer 。 编写 test_timer.py 如下 # coding:utf-8 """ 装饰器函数 运行计时器 "&…

C语言初阶习题【25】strcpy的模拟实现

1. 首先先调用下库函数,看它实现了什么 2. 我们自己实现一个strcpy函数 3. 改进1 把*destnation和source 写上去,使用后置 4. 改进2 这里直接把赋值操作放到了while的判断条件里面,然后while循环语句什么都不做,放了一个空语句…

使用 SQL 和表格数据进行问答和 RAG(6)—将指定目录下的 CSV 或 Excel 文件导入 SQLite 数据库

将指定目录下的 CSV 或 Excel 文件导入 SQLite 数据库。以下是详细代码逻辑: 1. 类结构 该类包含三个主要方法: _prepare_db:负责将文件夹中的 CSV 和 XLSX 文件转换为 SQL 表。_validate_db:用于验证 SQL 数据库中创建的表是否…

设计模式 行为型 策略模式(Strategy Pattern)与 常见技术框架应用 解析

策略模式(Strategy Pattern)核心思想是将算法的实现从使用该算法的类中分离出来,作为独立的对象,通过接口来定义算法家族,这样就可以很容易地改变或扩展算法。通过这种方式,可以避免在客户端代码中使用大量…

如何操作github,gitee,gitcode三个git平台建立镜像仓库机制,这样便于维护项目只需要维护一个平台仓库地址的即可-优雅草央千澈

如何操作github,gitee,gitcode三个git平台建立镜像仓库机制,这样便于维护项目只需要维护一个平台仓库地址的即可-优雅草央千澈 问题背景 由于我司最早期19年使用的是gitee,因此大部分仓库都在gitee有几百个库的代码,…

B+树的原理及实现

文章目录 B树的原理及实现一、引言二、B树的特性1、结构特点2、节点类型3、阶数 三、B树的Java实现1、节点实现2、B树操作2.1、搜索2.2、插入2.3、删除2.4、遍历 3、B树的Java实现示例 四、总结 B树的原理及实现 一、引言 B树是一种基于B树的树形数据结构,它在数据…

大纲笔记幕布的替换

文章目录 前言类似的大纲软件探索 DynalistLogseq通过国内代码仓库建立 Git 仓库Logseq 的使用PC 端安卓端Git 操作Termux git 步骤Termux 的桌面组件:Termux widget 报错参考 前言 之前我一直用幕布,买了三年,奈何要过期了,又三…

MoEs and Transformers 笔记

ref:https://huggingface.co/blog/zh/moe#%E7%94%A8router-z-loss%E7%A8%B3%E5%AE%9A%E6%A8%A1%E5%9E%8B%E8%AE%AD%E7%BB%83 MoEs and Transformers Transformer 类模型明确表明,增加参数数量可以提高性能,因此谷歌使用 GShard 尝试将 Transformer 模型…

ubuntu为Docker配置代理

终端代理 我们平常在ubuntu终端中使用curl或git命令时,往往会很慢。 所以,首先需要给ubuntu终端环境添加代理。 查看自身那个软件的端口号,我这里是7890。 sudo gedit ~/.bashrcexport http_proxyhttp://localhost:7890 export https_pr…

【安卓开发】【Android Studio】项目构建失败提示【Could not read metadata.bin】解决方法

一、问题说明 在Android Studio中开发安卓项目时,项目构建失败,提示如下: Could not read workspace data from xxx/xxx/(某个目录,和gradle有关):could not read ...metadata.bin&#xff08…

EXCEL: (二) 常用图表

10. 图表 134-添加.删除图表元素 图表很少是一个单独的整体,而是由十几种元素/对象拼凑出来的。 学习图表就是学习当中各类元素的插删改。 ①图表中主要元素的定义 图表上的一个颜色就是一个系列。 横轴是分类轴,将每个系列都分为几类。 ②选中图…

【AniGS】论文阅读

笔记目录 1. 基本信息2. 理解(个人初步理解,随时更改)1. 基本信息 题目:AniGS: Animatable Gaussian Avatar from a Single Image with Inconsistent Gaussian Reconstruction时间:2024.12发表:arxiv机构:Alibaba等作者:Lingteng Qiu等链接直达:Project关键词:img to…

ubuntu20.04 在线安装postgresql 扩展postgis

基础配置 /etc/apt/sources.list # 添加pg官方基础配置deb http://apt.postgresql.org/pub/repos/apt/ focal-pgdg main# 添加ubuntu官方依赖(防止下载依赖错误)deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse de…

【单片机】实现一个简单的ADC滤波器

实现一个 ADC的滤波器,PT1 滤波器(也称为一阶低通滤波器),用于对输入信号进行滤波处理。 typedef struct PT1FilterSettings PT1FilterSettings; struct PT1FilterSettings {//! last Filter output valueuint32_t filtValOld;//…

Kafka-go语言一命速通

记录 命令(终端操作kafka) # 验证kafka是否启动 ps -ef | grep kafka # ps -ef 命令用于显示所有正在运行的进程的详细信息 lsof -i :9092# 启动kafka brew services start zookeeper brew services start kafka# 创建topic kafka-topics --create --topic test --p…

sys.dm_exec_connections:查询与 SQL Server 实例建立的连接有关的信息以及每个连接的详细信息(客户端ip)

文章目录 引言I 基于dm_exec_connections查询客户端ip权限物理联接时间范围dm_exec_connections表see also: 监视SQL Server 内存使用量资源信号灯 DMV sys.dm_exec_query_resource_semaphores( 确定查询执行内存的等待)引言 查询历史数据库客户端ip应用场景: 安全分析缺乏…