控制机
ansible.cfg
callback_plugins = /usr/share/ansible/plugins/callback:/opt/ansible/plugins/callback
[ssh_connection]
ssh_args = -F /opt/ansible/ssh/ssh_config -o ControlMaster=auto -o ControlPersist=5m
control_path = /opt/ansible/ssh/ansible-ssh-%%h-%%p-%%r
pipelining = True
ssh_config
Host 69.169.xx.xx
User ansible
Port 29922
ForwardAgent yes
StrictHostKeyChecking no
Host 10.150.1.*
User ansible
Port 29922
ProxyCommand ssh -p 29922 ansible@69.169.xx.xx -W %h:%p
ForwardAgent yes
StrictHostKeyChecking no
Host 173.45.xx.xx
User ansible
Port 29922
ForwardAgent yes
StrictHostKeyChecking no
Host 10.160.1.*
User ansible
Port 29922
ProxyCommand ssh -p 29922 ansible@173.45.xx.xx -W %h:%p
ForwardAgent yes
StrictHostKeyChecking no
inventory
[dc]
69.169.xx.xx
[la]
173.45.xx.xx
[proxy-dc]
10.150.1.219
10.150.1.220
[proxy-la]
10.160.1.219
10.160.1.220
change_link.yaml
- hosts: proxy-dc
gather_facts: no
vars:
proxy_host: '221.228.xx.xx'
tasks:
- name: update /etc/hosts
template: src=templates/hosts.j2 dest=/etc/hosts owner=root group=root mode=0644
notify: restart dnsmasq
handlers:
- name: restart dnsmasq
service: name=dnsmasq state=restarted
demo example_play.py
以ansible用户身份登录远程机房内网服务器,sudo切换root权限,返回服务器的网卡流量、连接数、hosts指向
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
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
def play_task(host, nic):
class ResultCallback(CallbackBase):
def __init__(self, *args, **kwargs):
self.results = None
def v2_runner_on_unreachable(self, result):
ip = result._host.get_name()
self.results = (ip, '', '', '', '')
def v2_runner_on_failed(self, result, *args, **kwargs):
ip = result._host.get_name()
self.results = (ip, '', '', '', '')
def v2_runner_on_ok(self, result, *args, **kwargs):
ip = result._host.get_name()
traffic_in = result._result['link_info']['in']
traffic_out = result._result['link_info']['out']
connection = result._result['link_info']['connection']
current_link = result._result['link_info']['current_link']
self.results = (ip, traffic_in, traffic_out, connection, current_link)
Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check'])
variable_manager = VariableManager()
loader = DataLoader()
options = Options(
connection = 'ssh',
module_path = '/opt/ansible/plugins',
forks = 100,
become = True,
become_method = 'sudo',
become_user = 'root',
check = False
)
passwords = dict(vault_pass='secret')
results_callback = ResultCallback()
inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list='/opt/ansible/inventory')
variable_manager.set_inventory(inventory)
play_source = dict(
name = 'Ansible Play',
hosts = host,
gather_facts = 'no',
tasks = [
dict(action=dict(module='link_info', args='interface=%s' % nic)),
]
)
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
tqm = None
try:
tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
options=options,
passwords=None,
stdout_callback=results_callback,
)
tqm.run(play)
finally:
if tqm is not None:
tqm.cleanup()
return results_callback.results
link_info模块
#!/usr/bin/env python
# -*- coding: utf-8 -*-
DOCUMENTATION = '''
---
'''
EXAMPLES = '''
---
'''
import re, socket
import datetime, time
import subprocess
from ansible.module_utils.basic import *
def unit_convert(data):
if data < 10**3:
return str(round(float(data), 2))
elif data > 10**3 and data < 10**6:
return str(round(float(data) / 10**3, 2)) + 'Kb'
elif data > 10**6 and data < 10**9:
return str(round(float(data) / 10**6, 2)) + 'Mb'
elif data > 10**9 and data < 10**12:
return str(round(float(data) / 10**9, 2)) + 'Gb'
elif data > 10**12 and data < 10**15:
return str(round(float(data) / 10**12, 2)) + 'Tb'
def get_traffic_info():
proc_stat = '/proc/net/dev'
traffic = []
with open(proc_stat, 'r') as f:
for line in f:
m = re.match('\s*(\S+):\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+', line)
if m:
traffic.append((m.group(1), int(m.group(2)), int(m.group(10))))
return traffic
def get_connection_info():
command = 'netstat -n |grep ^tcp |wc -l'
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = p.communicate()
return int(output)
def get_current_link_info():
hostfile = '/etc/hosts'
with open(hostfile, 'r') as f:
for line in f:
m = re.match('(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(\S+)', line)
if m and m.group(2) == 'wx.service.live.tvmining.com':
return m.group(1)
return 'unknown'
def main():
module = AnsibleModule(
argument_spec = {
'interface': { 'default': 'em2', 'type': 'str'}
},
supports_check_mode = True
)
counter = 2
first = get_traffic_info()
time.sleep(counter)
second = get_traffic_info()
traffic = map(lambda x, y: (x[0], unit_convert(abs(x[1]-y[1])*8), unit_convert(abs(x[2]-y[2])*8)), first, second)
for name, receive, transmit in traffic:
if name == module.params['interface']:
traffic_in, traffic_out = receive, transmit
connection = get_connection_info()
current_link = get_current_link_info()
message = {
'in': traffic_in,
'out': traffic_out,
'connection': connection,
'current_link': current_link,
}
module.exit_json(changed=False, link_info=message)
if __name__ == '__main__':
main()
demo example_playbook.py
以ansible身份登录远程内网服务器,sudo切换root权限,执行change_link.yaml
#!/usr/bin/env python
# -*- coding: utf-8 -*-
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
from ansible.executor.playbook_executor import PlaybookExecutor
Options = namedtuple('Options', \
['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'listhosts', 'listtasks', 'listtags', 'syntax'])
# 这些options项是必须的,缺少的话程序报错
options = Options(
connection = 'ssh',
module_path = '/path/to/mymodules',
forks = 100,
become = True,
become_method = 'sudo',
become_user = 'root',
check = False,
listhosts = None,
listtasks = None,
listtags = None,
syntax = None
)
loader = DataLoader()
variable_manager = VariableManager()
inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list='/opt/ansible/inventory')
variable_manager.set_inventory(inventory)
playbooks=['/opt/ansible/change_link.yaml']
pb = PlaybookExecutor(playbooks=playbooks, inventory=inventory, variable_manager=variable_manager, loader=loader, options=options, passwords=None)
pb.run()