A description of the application scenario
Do you have this? A requirement: The number of ports used by Java programs on many servers is compared with the normal values.
You can use the following command to get the result:
Netstat-tulnp|grep java|wc-l
But a lot of servers, each manual to execute this command is not realistic. So think of using ansible batch to execute, ansible use Paramiko to SSH login server execute command, and use mutilprocessing to implement multi-process SSH login.
Two-code implementation
If you use ansible directly, do not make any processing. This is the case:
# ansible-i Qa_servers.txt all--private-key=/root/.ssh/id_rsa-m shell-a "Netstat-tulnp|grep java|wc-l" 172.30.25.71 | Success | Rc=0 >>3172.30.25.179 | Success | Rc=0 >>19172.30.25.180 | Success | Rc=0 >>86172.30.25.181 | Success | Rc=0 >>82
Ansible is the command executed by the ansible command,-I specify the Hosts file--private-key specify the SSH private key path-m specifies the module to be called, where the shell module is called
-a specifies the parameters passed to the module, which is both the command to execute
Here are a few questions:
A. The number of normal Java ports on each server is different and needs to be compared and confirmed with the normal values, it is best to print out the results
B. Calling ansible directly on the command line while executing commands on each server, the output is not standardized and needs to be further processed.
Ansible was originally developed by Python, and all the code is in the/usr/lib/python2.6/site-packages/ansible/directory after installing Ansible. So you can read the Ansible source code as a normal Python code.
Then, by looking at the code examples ansible official website, I learned that ansible execute commands are all through
The run function of the runner class in the/usr/lib/python2.6/site-packages/ansible/runner/__init__.py code executes
So to further process the output of the ansible, first get the details of the ansible invoke command execution.
The complete code is as follows:
import ansible.runnerfrom ansible.color import stringchost_list= ' Qa_servers.txt ' Private_ Key_file= '/root/.ssh/id_rsa ' pattern= ' * ' forks=10timeout=30module_name= ' shell ' # construct the Ansible runner and execute on all hostsresults = ansible.runner.runner (Host_list=host_list,private_key_file=private_key_file,pattern=pattern,forks=forks,timeout=timeout,module_name =module_name,module_args=module_args ). Run () #print resultsif results is None: print "no hosts found " sys.exit (1) PRINT STRINGC (" +-------------------+----------------------+----- --------+-----------+--------+ ", color= ' cyan ') PRINT STRINGC (" | host | HOSTNAME | chicked num | right num | status | ", color= ' cyan ') PRINT STRINGC ("+-------------------+----------------------+-------------+-----------+--------+", color= ' Cyan ') for (hostname, result) in results[' contacted '].items (): if not ' failed ' in result: num_default=int ( Subprocess. Popen (' awk '/%s/{print $3} ' %s|sed -n ' s/#//p ' ' % (hostname,host_ list), shell=true,stdout=subprocess. PIPE). Communicate () [0].split (' \ n ') [0]] num=int (result[' stdout ') . split (' \ n ') [0]) host_name=result[' stdout '].split (' \ n ') [1] if num==num_default:         STATUS=STRINGC (' PASS ', color= ' green ')     ELSE:           STATUS=STRINGC ( ' WARN ', color= ' Red ')         PRINT STRINGC ("| %-17s | %-20s | %-11d | %-9d | %-12s ", color= ' cyan ') % ( Hostname,host_name,num,num_default,status)  + STRINGC ("|", color= ' cyan ')    PRINT STRINGC ("+-------------------+----------------------+-------------+-----------+-- ------+ ", color= ' cyan ') # print "%s >>> % S " % (hostname, result[' stdout ') #print " failed ******* "#for (hostname, Result) in results[' contacted '].items ():# if ' failed ' in Result:# print "%s >>> %s" % (hostname, result[' msg]) #print "down *********" #for (hostname, result) in results[' Dark '].items (): # print "%s >>> %s" % (Hostname, result)
The contents of Qa_servers.txt are as follows:
172.30.25.71 #testt #3172.30.25.179 #testttttttt179 #30172.30.25.180 #testttttttt180 #45172 .30.25.181 #testttttttt181 #55172.30.25.172 #test #68172.30.25.173 #test #7
The first column is the host IP or host name of the command to be executed, the second column is the hostname, and the third column is the number of ports that the normal Java program occupies. The second and third columns must be commented out. Ansible recognizes only the first column when the host is recognized.
The result of executing the code is as follows:
+-------------------+----------------------+-------------+-----------+--------+| host | HOSTNAME | CHICKED NUM | RIGHT NUM | status |+-------------------+----------------------+-------------+-----------+--------+| 172.30.25.180 | testtesttesttt | 86 | 45 | warn |+-------------------+----------------------+-------------+---- -------+--------+| 172.30.25.181 | testttttttt181 | 82 | 55 | warn |+-------------------+----------------------+-------------+-----------+- -------+| 172.30.25.179 | testttttttt179 | 19 | 30 | warn |+-------------------+----------------------+------ -------+-----------+--------+| 172.30.25.71 | testt | 3 | 3 | pass |+-------------------+----------------------+-------------+-----------+--------+
Resources:
Http://docs.ansible.com/ansible/developing_api.html
This article is from the Linux SA John blog, so be sure to keep this source http://john88wang.blog.51cto.com/2165294/1732982
Ansible two times development to check the server's Java program occupies the number of ports