-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathscan_processes.py
153 lines (133 loc) · 5.01 KB
/
scan_processes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/python
# Copyright: (c) 2019, Andrew J. Huffman <[email protected]>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: scan_processes
short_description: Collects currently running processes on a system
version_added: "2.8"
description:
- "Collects the currently running processes on a system at the time the module is run."
- "This module presents the currently running proceses as ansible_facts"
output_ps_stdout_lines:
description:
- Whether or not to output the collected standard out lines from the 'ps auxww' command
default: False
required: False
output_parsed_processes:
description:
- Whether or not to output parsed data from the 'ps auxww' command.
default: True
required: False
author:
- Andrew J. Huffman (@ahuffman)
'''
EXAMPLES = '''
# Collect running processes and output parsed data
- name: "Collect current running processes"
scan_processes:
# Collect only standard out lines from the ps auxww command
- name: "Collect process command output"
scan_processes:
output_ps_stdout_lines: True
output_parsed_processes: False
# Collect both parsed process data and 'ps auxww' command standard out
- name: "Collect all process data"
scan_processes:
output_ps_stdout_lines: True
'''
RETURN = '''
running_processes:
processes:
- command: /usr/lib/systemd/systemd --switched-root --system --deserialize 33
cpu_percentage: '0.0'
memory_percentage: '0.0'
pid: '1'
resident_size: '5036'
start: Jul08
stat: Ss
teletype: '?'
time: '3:32'
user: root
...
ps_stdout_lines:
- root 1 0.0 0.0 171628 5056 ? Ss Jul08 3:32 /usr/lib/systemd/systemd --switched-root --system --deserialize 33
...
total_running_processes: 359
'''
from ansible.module_utils.basic import AnsibleModule
import os, re, subprocess
from os.path import isfile, isdir, join
def main():
module_args = dict(
output_ps_stdout_lines=dict(
type='bool',
default=False,
required=False
),
output_parsed_processes=dict(
type='bool',
default=True,
required=False
)
)
result = dict(
changed=False,
original_message='',
message=''
)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True
)
params = module.params
def get_processes():
re_header = re.compile(r'^USER+.*')
proc_stats = dict()
procs = list()
count = 0
running = subprocess.check_output(["ps auxww"], universal_newlines=True, shell=True)
for l in running.split('\n'):
if len(l) > 0 and re_header.search(l) is None:
procs.append(l.replace('\n', '').replace('\t', ' '))
count += 1
proc_stats['stdout'] = procs
proc_stats['total_running_processes'] = count
return proc_stats
def parse_process_data(procs):
re_ps = re.compile(r'^(?P<user>[\w\+\-\_\$]+)\s+(?P<pid>[0-9]+)\s+(?P<cpu>[0-9\.]+)\s+(?P<mem>[0-9\.]+)\s+(?P<vsz>[0-9]+)\s+(?P<rss>[0-9]+)\s+(?P<tty>[a-zA-Z0-9\?\/]+)\s+(?P<stat>[DIRSTtWXZ\<NLsl\+]+)\s+(?P<start>[A-Za-z0-9\:]+)\s+(?P<time>[0-9\:]+)\s+(?P<command>.*)$')
processes = list()
for proc in procs:
process = dict()
if re_ps.search(proc):
process['user'] = re_ps.search(proc).group('user')
process['pid'] = re_ps.search(proc).group('pid')
process['cpu_percentage'] = re_ps.search(proc).group('cpu')
process['memory_percentage'] = re_ps.search(proc).group('mem')
process['virtual_memory_size'] = re_ps.search(proc).group('vsz')
process['resident_size'] = re_ps.search(proc).group('rss')
process['teletype'] = re_ps.search(proc).group('tty')
process['stat'] = re_ps.search(proc).group('stat')
process['start'] = re_ps.search(proc).group('start')
process['time'] = re_ps.search(proc).group('time')
process['command'] = re_ps.search(proc).group('command')
processes.append(process)
return processes
# Do work
raw_procs = get_processes()
if params['output_parsed_processes']:
proc_data = parse_process_data(raw_procs['stdout'])
# Build output
processes = dict()
if params['output_ps_stdout_lines']:
processes['ps_stdout_lines'] = raw_procs['stdout']
if params['output_parsed_processes']:
processes['total_running_processes'] = raw_procs['total_running_processes']
processes['processes'] = proc_data
result = {'ansible_facts': {'running_processes': processes}}
module.exit_json(**result)
if __name__ == '__main__':
main()