1.ansible核心类介绍
核心类 用途 所在模块路径
CallbackBase 状态回调,各种成功失败的状态 ansible.plugins.callback
InventoryManager 用于导入inventory文件 ansible.inventory.manager
VariableManager 用于存储各类变量信息 ansible.vars.manager
Host, Group 操作单个主机或者主机组信息 ansible.inventory.host

![屏幕截图-[美河学习在线 eimhe.com]7-2 ansible模块中的核心类介绍.mp4-1](ansible-核心api/屏幕截图-[美河学习在线 eimhe.com]7-2 ansible模块中的核心类介绍.mp4-1.png)

2.InventotyManager
1
from ansible.inventory.manager import InventoryManager
2
from ansible.parsing.dataloader import DataLoader
3
from ansible.vars.manager import VariableManager
4
from ansible.playbook.play import Play
5
from ansible.executor.task_queue_manager import TaskQueueManager
6
from ansible.plugins.callback import CallbackBase
7
8
loader = DataLoader()
9
inventory = InventoryManager(loader=loader, sources=['hosts'])
10
11
VariableManager(loader=loader, inventory=inventory)
  • 添加主机到指定主机add_host()

    1
    In [38]: inventory.add_host(host='192.168.1.103', port=22, group='test')                 
    2
    In [39]: inventory.get_groups_dict()                                                     
    3
    Out[39]: 
    4
    {'all': ['47.104.148.179', '192.168.1.103'],
    5
     'ungrouped': [],
    6
     'test': ['47.104.148.179', '192.168.1.103']}
  • 查看主机组资源get_groups_dict()

    1
    In [34]: inventory = InventoryManager(loader=loader, sources=['hosts'])
    2
    In [35]: inventory.get_groups_dict()                                                     
    3
    Out[35]: {'all': ['47.104.148.179'], 'ungrouped': [], 'test': ['47.104.148.179']}
  • 获取指定的主机对象get_hosts()

    1
    In [37]: inventory.get_hosts()                                                        
    2
    Out[37]: [47.104.148.179]
    3
    4
    In [43]: inventory.get_host(hostname='192.168.1.103')
    5
    Out[43]: 192.168.1.103
3.VariableManager
1
In [45]: variable_manager = VariableManager(loader=loader, inventory=inventory)                                                         
2
3
In [46]: variable_manager                                                                                                               
4
Out[46]: <ansible.vars.manager.VariableManager at 0x7fc4961c3f60>
5
6
In [47]: variable_manager.get_vars()                                                                                                    
7
Out[47]: 
8
{'playbook_dir': '/home/ykyk/DB_manager/scripts/ansible_modules',
9
 'ansible_playbook_python': '/home/ykyk/Envs/python37/bin/python',
10
 'groups': {'all': ['47.104.148.179', '192.168.1.103'],
11
  'ungrouped': [],
12
  'test': ['47.104.148.179', '192.168.1.103']},
13
 'omit': '__omit_place_holder__6e4c7c2fcf2bfa2083ee8fea862bfbc116046914'}
  • 查看变量get_vars()

    1
    In [49]: host = inventory.get_host(hostname='47.104.148.179')                                                                           
    2
    3
    In [50]: variable_manager.get_vars(host=host)                                                                                           
    4
    Out[50]: 
    5
    {'inventory_file': '/home/ykyk/DB_manager/scripts/ansible_modules/hosts',
    6
     'inventory_dir': '/home/ykyk/DB_manager/scripts/ansible_modules',
    7
     'inventory_hostname': '47.104.148.179',
    8
     'inventory_hostname_short': '47',
    9
     'group_names': ['test'],
    10
     'ansible_facts': {},
    11
     'playbook_dir': '/home/ykyk/DB_manager/scripts/ansible_modules',
    12
     'ansible_playbook_python': '/home/ykyk/Envs/python37/bin/python',
    13
     'groups': {'all': ['47.104.148.179', '192.168.1.103'],
    14
      'ungrouped': [],
    15
      'test': ['47.104.148.179', '192.168.1.103']},
    16
     'omit': '__omit_place_holder__6e4c7c2fcf2bfa2083ee8fea862bfbc116046914'}
  • 设置主机变量方法set_host_variable()

    1
    variable_manager.set_host_variable(host=host, varname='ykyk', value='xxxxxxx')  
    2
    3
    In [52]: variable_manager.get_vars(host=host)                                                                                           
    4
    Out[52]: 
    5
    {'inventory_file': '/home/ykyk/DB_manager/scripts/ansible_modules/hosts',
    6
     'inventory_dir': '/home/ykyk/DB_manager/scripts/ansible_modules',
    7
     'inventory_hostname': '47.104.148.179',
    8
     'inventory_hostname_short': '47',
    9
     'group_names': ['test'],
    10
     'ansible_facts': {},
    11
     'ykyk': 'xxxxxxx',
    12
     'playbook_dir': '/home/ykyk/DB_manager/scripts/ansible_modules',
    13
     'ansible_playbook_python': '/home/ykyk/Envs/python37/bin/python',
    14
     'groups': {'all': ['47.104.148.179', '192.168.1.103'],
    15
      'ungrouped': [],
    16
      'test': ['47.104.148.179', '192.168.1.103']},
    17
     'omit': '__omit_place_holder__6e4c7c2fcf2bfa2083ee8fea862bfbc116046914'}
  • 添加扩展变量

    1
    In [53]: variable_manager.extra_vars={"website": "yangkai.org.cn", "name": "ykyk"}                                                      
    2
    3
    In [54]: variable_manager.get_vars(host=host)                                                                                           
    4
    Out[54]: 
    5
    {'inventory_file': '/home/ykyk/DB_manager/scripts/ansible_modules/hosts',
    6
     'inventory_dir': '/home/ykyk/DB_manager/scripts/ansible_modules',
    7
     'inventory_hostname': '47.104.148.179',
    8
     'inventory_hostname_short': '47',
    9
     'group_names': ['test'],
    10
     'ansible_facts': {},
    11
     'ykyk': 'xxxxxxx',
    12
     'website': 'yangkai.org.cn',
    13
     'name': 'ykyk',
    14
     'playbook_dir': '/home/ykyk/DB_manager/scripts/ansible_modules',
    15
     'ansible_playbook_python': '/home/ykyk/Envs/python37/bin/python',
    16
     'groups': {'all': ['47.104.148.179', '192.168.1.103'],
    17
      'ungrouped': [],
    18
      'test': ['47.104.148.179', '192.168.1.103']},
    19
     'omit': '__omit_place_holder__6e4c7c2fcf2bfa2083ee8fea862bfbc116046914'}
4.ad-hoc模式调用
1
ansible -m command -a 'ls /tmp' test -i /etc/ansible/hosts -f 5
  • 执行对象和模块
  • 资源资产配置清单
  • 执行选项
1
from ansible.inventory.manager import InventoryManager
2
from ansible.parsing.dataloader import DataLoader
3
from ansible.vars.manager import VariableManager
4
from ansible.playbook.play import Play
5
from ansible.executor.task_queue_manager import TaskQueueManager
6
from ansible.plugins.callback import CallbackBase
7
from collections import namedtuple
8
9
loader = DataLoader()
10
inventory = InventoryManager(loader=loader, sources=['hosts'])
11
12
variable_manager = VariableManager(loader=loader, inventory=inventory)
13
14
# 执行选项
15
Options = namedtuple ('Options',
16
                     ['connection',
17
                      'remote_user',
18
                      'ask_sudo_pass',
19
                      'ack_pass',
20
                      'module_path',
21
                      'forks',
22
                      'become',
23
                      'become_method',
24
                      'become_user',
25
                      'check',
26
                      # 'verbosity'
27
                      'listhosts',
28
                      # 'listtasks',
29
                      # 'listtags',
30
                      # 'syntax',
31
                      'sudo_user',
32
                      'sudo',
33
                      'diff']
34
                     )
35
36
37
options = Options(connection='smart',
38
                  remote_user='root',
39
                  ack_pass=None,
40
                  sudo_user=None,
41
                  forks=5,
42
                  ask_sudo_pass=None,
43
                  # verbosity=5,
44
                  # verbositysudo=None,
45
                  module_path=None,
46
                  become=None,
47
                  become_method=None,
48
                  become_user=None,
49
                  listhosts=None,
50
                  check=False,
51
                  diff=False,
52
                  sudo=False)
53
                  # diff=False)
54
55
                  # listtasks=None,
56
                  # listtags=None,
57
                  # syntax=None)
58
59
play_source = dict(
60
    name = 'ykyk', #任务名称
61
    hosts = '47.104.148.179', # 目标主机
62
    gather_facts = 'no', # 获取主机基本信息
63
    tasks = [
64
        dict(action=dict(module='shell', args='touch /tmp/aaa.log')),
65
    ]
66
)
67
68
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
69
70
71
passwords = dict()
72
73
tqm = TaskQueueManager(
74
    inventory=inventory,
75
    variable_manager=variable_manager,
76
    loader=loader,
77
    options=options,
78
    passwords=passwords
79
)
80
81
result = tqm.run(play)
82
print(result)
1
PLAY [ykyk] ********************************************************************
2
3
TASK [shell] *******************************************************************
4
changed: [47.104.148.179]
5
 [WARNING]: Consider using the file module with state=touch rather than running
6
'touch'.  If you need to use command because file is insufficient you can add
7
'warn: false' to this command task or set 'command_warnings=False' in
8
ansible.cfg to get rid of this message.
9
0
1
[root@ykyk ~]# ls /tmp/
2
aaa.log                                             mysqlx.sock.lock
5.playbook模式调用
1
$ ansible-playbook test.yml -i /etc/ansible/host -f 5
1
from ansible.inventory.manager import InventoryManager
2
from ansible.parsing.dataloader import DataLoader
3
from ansible.vars.manager import VariableManager
4
from ansible.playbook.play import Play
5
from ansible.executor.task_queue_manager import TaskQueueManager
6
from ansible.executor.playbook_executor import PlaybookExecutor
7
from ansible.plugins.callback import CallbackBase
8
from collections import namedtuple
9
10
loader = DataLoader()
11
inventory = InventoryManager(loader=loader, sources=['hosts'])
12
13
variable_manager = VariableManager(loader=loader, inventory=inventory)
14
15
# 执行选项
16
Options = namedtuple ('Options',
17
                     ['connection',
18
                      'remote_user',
19
                      'ask_sudo_pass',
20
                      'ack_pass',
21
                      'module_path',
22
                      'forks',
23
                      'become',
24
                      'become_method',
25
                      'become_user',
26
                      'check',
27
                      # 'verbosity'
28
                      'listhosts',
29
                      'listtasks',
30
                      'listtags',
31
                      'syntax',
32
                      'sudo_user',
33
                      'sudo',
34
                      'diff']
35
                     )
36
37
38
options = Options(connection='smart',
39
                  remote_user='root',
40
                  ack_pass=None,
41
                  sudo_user=None,
42
                  forks=5,
43
                  ask_sudo_pass=None,
44
                  # verbosity=5,
45
                  # verbositysudo=None,
46
                  module_path=None,
47
                  become=None,
48
                  become_method=None,
49
                  become_user=None,
50
                  listhosts=None,
51
                  check=False,
52
                  diff=False,
53
                  listtasks=None,
54
                  listtags=None,
55
                  syntax=False,
56
                  sudo=False)
57
                  # diff=False)
58
59
60
                  # listtags=None,
61
                  # syntax=None)
62
63
play_source = dict(
64
    name = 'ykyk', #任务名称
65
    hosts = '47.104.148.179', # 目标主机
66
    gather_facts = 'no', # 获取主机基本信息
67
    tasks = [
68
        dict(action=dict(module='shell', args='touch /tmp/aaa.log')),
69
    ]
70
)
71
72
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
73
74
75
# passwords = dict()
76
#
77
# tqm = TaskQueueManager(
78
#     inventory=inventory,
79
#     variable_manager=variable_manager,
80
#     loader=loader,
81
#     options=options,
82
#     passwords=passwords
83
# )
84
#
85
# result = tqm.run(play)
86
# print(result)
87
88
# playbook
89
90
passwords = dict()
91
playbook = PlaybookExecutor(playbooks=['test.yml'],
92
                            inventory=inventory,
93
                            variable_manager=variable_manager,
94
                            loader=loader,
95
                            options=options,
96
                            passwords=passwords)
97
98
playbook.run()
1
PLAY [47.104.148.179] **********************************************************
2
3
TASK [Gathering Facts] *********************************************************
4
ok: [47.104.148.179]
5
6
TASK [touch file] **************************************************************
7
 [WARNING]: Consider using the file module with state=touch rather than running
8
'touch'.  If you need to use command because file is insufficient you can add
9
'warn: false' to this command task or set 'command_warnings=False' in
10
ansible.cfg to get rid of this message.
11
changed: [47.104.148.179]
12
13
PLAY RECAP *********************************************************************
14
47.104.148.179             : ok=2    changed=1    unreachable=0    failed=0

result:

1
[root@ykyk blog]# cd /tmp/
2
[root@ykyk tmp]# ls
3
aaa.log                                             ssh-IOXeDgEQx2
4
Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>  systemd-private-4d657052127a445a83c171415365485e-nginx.service-V2IIFO
5
hello.c                                             systemd-private-4d657052127a445a83c171415365485e-ntpd.service-tbn2Wn
6
mysqlx.sock                                         test_playbook
6.callback改写

自定义格式输出

  • 通过子类继承父类(callbackbase)
  • 通过子类改写父类的部分方法
    • v2_runner_on_unreachable
    • v2_runner_on_ok
    • v2_runner_on_failed
1
from ansible.inventory.manager import InventoryManager
2
from ansible.parsing.dataloader import DataLoader
3
from ansible.vars.manager import VariableManager
4
from ansible.playbook.play import Play
5
from ansible.executor.task_queue_manager import TaskQueueManager
6
from ansible.executor.playbook_executor import PlaybookExecutor
7
from ansible.plugins.callback import CallbackBase
8
from collections import namedtuple
9
10
loader = DataLoader()
11
inventory = InventoryManager(loader=loader, sources=['hosts'])
12
13
variable_manager = VariableManager(loader=loader, inventory=inventory)
14
15
# 执行选项
16
Options = namedtuple ('Options',
17
                     ['connection',
18
                      'remote_user',
19
                      'ask_sudo_pass',
20
                      'ack_pass',
21
                      'module_path',
22
                      'forks',
23
                      'become',
24
                      'become_method',
25
                      'become_user',
26
                      'check',
27
                      # 'verbosity'
28
                      'listhosts',
29
                      'listtasks',
30
                      'listtags',
31
                      'syntax',
32
                      'sudo_user',
33
                      'sudo',
34
                      'diff']
35
                     )
36
37
38
options = Options(connection='smart',
39
                  remote_user='root',
40
                  ack_pass=None,
41
                  sudo_user=None,
42
                  forks=5,
43
                  ask_sudo_pass=None,
44
                  # verbosity=5,
45
                  # verbositysudo=None,
46
                  module_path=None,
47
                  become=None,
48
                  become_method=None,
49
                  become_user=None,
50
                  listhosts=None,
51
                  check=False,
52
                  diff=False,
53
                  listtasks=None,
54
                  listtags=None,
55
                  syntax=False,
56
                  sudo=False)
57
                  # diff=False)
58
59
60
                  # listtags=None,
61
                  # syntax=None)
62
63
play_source = dict(
64
    name = 'ykyk', #任务名称
65
    hosts = '47.104.148.179', # 目标主机
66
    gather_facts = 'no', # 获取主机基本信息
67
    tasks = [
68
        dict(action=dict(module='shell', args='touch /tmp/aaa.log')),
69
    ]
70
)
71
72
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
73
74
75
# passwords = dict()
76
#
77
# tqm = TaskQueueManager(
78
#     inventory=inventory,
79
#     variable_manager=variable_manager,
80
#     loader=loader,
81
#     options=options,
82
#     passwords=passwords
83
# )
84
#
85
# result = tqm.run(play)
86
# print(result)
87
88
# playbook
89
90
# passwords = dict()
91
# playbook = PlaybookExecutor(playbooks=['test.yml'],
92
#                             inventory=inventory,
93
#                             variable_manager=variable_manager,
94
#                             loader=loader,
95
#                             options=options,
96
#                             passwords=passwords)
97
#
98
# playbook.run()
99
100
class ModelResultsCollector(CallbackBase):
101
102
    def __init__(self, *args, **kwargs):
103
        super(ModelResultsCollector, self).__init__(*args, **kwargs)
104
        self.host_ok = {}
105
        self.host_unreachable = {}
106
        self.host_failed = {}
107
108
    def v2_runner_on_unreachable(self, result):
109
        self.host_unreachable[result._host.get_name()] = result
110
111
    def v2_runner_on_ok(self, result, *args, **kwargs):
112
        self.host_ok[result._host.get_name()] = result
113
114
    def v2_runner_on_failed(self, result, ignore_errors=False, *args, **kwargs):
115
        self.host_failed[result._host.get_name()] = result
116
117
callback = ModelResultsCollector()
118
119
passwords = dict()
120
tqm = TaskQueueManager(
121
    inventory=inventory,
122
    variable_manager=variable_manager,
123
    loader=loader,
124
    options=options,
125
    passwords=passwords,
126
    stdout_callback=callback
127
)
128
129
result = tqm.run(play)
130
print(callback.host_ok.items())
131
132
result_raw = {
133
    "success": {},
134
    "failed": {},
135
    "unreachable": {}
136
}
137
for host, result in callback.host_ok.items():
138
    result_raw['success'][host] = result._result
139
for host, result in callback.host_failed.items():
140
    result_raw['failed'][host] = result._result
141
for host, result in callback.host_unreachable.items():
142
    result_raw['unreachable'][host] = result._result
143
print(result_raw)

playbook 模式

1
class PlayBookResultsCollector(CallbackBase):
2
    CALLBACK_VERSION = 2.0
3
    def __init__(self, *args, **kwargs):
4
        super(PlayBookResultsCollector, self).__init__(*args, **kwargs)
5
        self.task_ok = {}
6
        self.task_skipped = {}
7
        self.task_failed = {}
8
        self.task_status = {}
9
        self.task_unreachable = {}
10
11
    def v2_runner_on_ok(self, result, *args, **kwargs):
12
        self.task_ok[result._host.get_name()]  = result
13
14
    def v2_runner_on_failed(self, result, *args, **kwargs):
15
        self.task_failed[result._host.get_name()] = result
16
17
    def v2_runner_on_unreachable(self, result):
18
        self.task_unreachable[result._host.get_name()] = result
19
20
    def v2_runner_on_skipped(self, result):
21
        self.task_ok[result._host.get_name()]  = result
22
23
    def v2_playbook_on_stats(self, stats):
24
        hosts = sorted(stats.processed.keys())
25
        for h in hosts:
26
            t = stats.summarize(h)
27
            self.task_status[h] = {
28
                                       "ok":t['ok'],
29
                                       "changed" : t['changed'],
30
                                       "unreachable":t['unreachable'],
31
                                       "skipped":t['skipped'],
32
                                       "failed":t['failures']
33
                                   }
1
passwords = dict()
2
playbook = PlaybookExecutor(playbooks=['test.yml'],
3
                            inventory=inventory,
4
                            variable_manager=variable_manager,
5
                            loader=loader,
6
                            options=options,
7
                            passwords=passwords)
8
playbook._tqm._stdout_callback = callback
9
playbook.run()
10
result_raw = {
11
    "changed": {},
12
    "failed": {},
13
    "unreachable": {},
14
    "skipped": {},
15
    "ok": {},
16
    "status": {}
17
}
18
for host, result in callback.task_ok.items():
19
    result_raw['ok'][host] = result._result
20
21
print(result_raw)

result

1
{
2
	'changed': {},
3
	'failed': {},
4
	'unreachable': {},
5
	'skipped': {},
6
	'ok': {
7
		'47.104.148.179': {
8
			'changed': True,
9
			'end': '2019-05-20 22:48:32.104922',
10
			'stdout': '',
11
			'cmd': 'touch /tmp/test_playbook',
12
			'rc': 0,
13
			'start': '2019-05-20 22:48:32.093947',
14
			'stderr': '',
15
			'delta': '0:00:00.010975',
16
			'invocation': {
17
				'module_args': {
18
					'creates': None,
19
					'executable': None,
20
					'_uses_shell': True,
21
					'_raw_params': 'touch /tmp/test_playbook',
22
					'removes': None,
23
					'argv': None,
24
					'warn': True,
25
					'chdir': None,
26
					'stdin': None
27
				}
28
			},
29
			'warnings': ["Consider using the file module with state=touch rather than running 'touch'.  If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message."],
30
			'_ansible_parsed': True,
31
			'stdout_lines': [],
32
			'stderr_lines': [],
33
			'_ansible_no_log': False
34
		}
35
	},
36
	'status': {}
37
}