因为小弟毕设做一个简单的自动化运维系统,所以入了ansible的坑,现在想把毕设过程中一些关键技术的核心代码做下记录,也希望通过此平台与大家相互交流学习,共同进步。
//一共有4个文件
[root@localhost playbook]# tree
.
├── config.yml
├── exec.py
├── hosts
└── secrets.yml
// 1)放置Inventory的文件
[root@localhost playbook]# cat hosts
[ios_device]
192.168.60.121
// 2)一些在playbook要用到的凭证参数变量
[root@localhost playbook]# cat secrets.yml
---
creds:
? username: cisco
? password: cisco
? auth_pass: cisco
// 3) 在Python代码中要引用的playbook
[root@localhost playbook]# cat config.yml
---
- hosts: ios_device
? gather_facts: no
? connection: local
? tasks:
? - name: OBTAIN LOGIN CREDENTIALS
? ? include_vars: secrets.yml
? - name: DEFINE PROVIDER
? ? set_fact:
? ? ? provider:
? ? ? ? host: "{{ inventory_hostname }}"
? ? ? ? username: "{{ creds['username'] }}"
? ? ? ? password: "{{ creds['password'] }}"
? ? ? ? auth_pass: "{{ creds['auth_pass'] }}"
? - name: show run
? ? ios_config:
? ? ? provider: "{{ provider }}"
? ? ? authorize: yes
? ? ? commands:
? ? ? ? - hostname cisco
? ? ? ? - ip access-list extended test
? ? ? ? - permit ip host 192.1.1.1 any log
? ? ? ? - exit
? ? ? ? - int f1/0
? ? ? ? - ip address 1.1.1.2 255.255.255.0
? ? ? ? - no shutdown
? ? ? ? - ip route 0.0.0.0 0.0.0.0 192.168.60.2
? ? ? ? - do write
// 4) 需要执行的Python 代码
[root@localhost playbook]# cat exec.py
#!/usr/bin/env?python
#?coding=utf-8
import?json
import?shutil
from?collections?import?namedtuple
from?ansible.parsing.dataloader?import?DataLoader
from?ansible.vars.manager?import?VariableManager
from?ansible.inventory.manager?import?InventoryManager
from?ansible.executor.playbook_executor?import?PlaybookExecutor
from?ansible.executor.task_queue_manager?import?TaskQueueManager
from?ansible.plugins.callback?import?CallbackBase
import?ansible.constants?as?C
class?ResultCallback(CallbackBase):
????def?__init__(self,?*args,?**kwargs):
????????super(ResultCallback,?self).__init__(*args,?**kwargs)
????????self.task_ok={}
????def?v2_runner_on_ok(self,?result,?*args,?**kwargs):
????????self.task_ok[result._host.get_name()]=result
results_callback?=?ResultCallback()
#InventoryManager类
loader?=?DataLoader()?????#读取yaml文件
inventory?=?InventoryManager(loader=loader,?sources=['./hosts'])#这里的路径要正确
#variableManager类
variable_manager?=?VariableManager(loader=loader,inventory=inventory)
#option?执行选项
Options?=?namedtuple('Optoins',
?????????????????????['connection',
??????????????????????'remote_user',
??????????????????????'ask_sudo_pass',
??????????????????????'verbosity',
??????????????????????'ack_pass',
??????????????????????'module_path',
??????????????????????'forks',
??????????????????????'become',
??????????????????????'become_method',
??????????????????????'become_user',
??????????????????????'check',
??????????????????????'listhosts',
??????????????????????'syntax',
??????????????????????'listtags',
??????????????????????'listtasks',
??????????????????????'sudo_user',
??????????????????????'sudo',
??????????????????????'diff'])
options?=?Options(connection='smart',
???????????????????remote_user=None,
???????????????????ack_pass=None,
???????????????????sudo_user=None,
???????????????????forks=5,
???????????????????sudo=None,
???????????????????ask_sudo_pass=False,
???????????????????verbosity=5,
???????????????????module_path=None,
???????????????????become=None,
???????????????????become_method=None,
???????????????????become_user=None,
???????????????????check=False,
???????????????????diff=False,
???????????????????listhosts=None,
???????????????????listtasks=None,
???????????????????listtags=None,
???????????????????syntax=None)
passwords=dict()
#playbook的路径要正确
playbook=PlaybookExecutor(playbooks=['config.yml'],
??????????????????????????inventory=inventory,
??????????????????????????variable_manager=variable_manager,
??????????????????????????loader=loader,
??????????????????????????options=options,
??????????????????????????passwords=passwords)
#playbook.run()
playbook._tqm._stdout_callback=results_callback
playbook.run()
results_raw={'ok':{}}
for?host,result?in?results_callback.task_ok.items():
????results_raw['ok'][host]=result._result
print?results_raw
——————————————————————
如果在命令行模式使用过ansible-playbook命令的话,可以很清楚的了解上诉代码编写过程 1.设置Inventory -> 2.设置选项参数 -> 3.设置引用剧本
class?ResultCallback(CallbackBase)?是为了返回的结果是json格式,方便前端调用。
运行结果:
//记得给.py文件于可执行权限:chmod?+x?exec.py
[root@localhost?playbook]#?./exec.py
{
'ok':?{
u?'192.168.60.121':?{
'_ansible_parsed':?True,
u?'src':?u?'/root/.ansible/tmp/ansible-tmp-1547048002.11-60187723412487/source',
u?'md5sum':?u?'28e89502d2362427b660aaf7ce762c37',
u?'group':?u?'root',
u?'uid':?0,
'_ansible_delegated_vars':?{
'ansible_delegated_host':?u?'localhost',
'ansible_host':?u?'localhost'
},
u?'dest':?u?'./192.168.60.121.txt',
u?'checksum':?u?'2006c7082ad427e6ebb0d61c2aefd2859fa51b35',
u?'changed':?True,
'_ansible_no_log':?False,
'failed':?False,
u?'state':?u?'file',
u?'gid':?0,
u?'mode':?u?'0644',
u?'invocation':?{
u?'module_args':?{
u?'directory_mode':?None,
u?'force':?True,
u?'remote_src':?None,
u?'owner':?None,
u?'follow':?False,
u?'local_follow':?None,
u?'group':?None,
u?'unsafe_writes':?None,
u?'setype':?None,
u?'content':?None,
u?'serole':?None,
u?'dest':?u?'./192.168.60.121.txt',
u?'selevel':?None,
u?'original_basename':?u?'tmpoMsJHe',
u?'regexp':?None,
u?'validate':?None,
u?'src':?u?'/root/.ansible/tmp/ansible-tmp-1547048002.11-60187723412487/source',
u?'seuser':?None,
u?'delimiter':?None,
u?'mode':?None,
u?'attributes':?None,
u?'backup':?False
}
},
u?'owner':?u?'root',
'diff':?[],
u?'size':?378
}
}
}
-------------结束-------------