service_facts: return service state information on AIX (#72073)
* service_facts: return service state information on AIX AIX uses the System Resource Controller (SRC) to manage services. See https://www.ibm.com/support/knowledgecenter/ssw_aix_72/osmanagement/sysrescon.htm Use lssrc command on AIX to return service state information. Co-authored-by: dberg1 <dberg1@github.com>
This commit is contained in:
parent
caba47dd3f
commit
cdf62edc65
3 changed files with 160 additions and 3 deletions
2
changelogs/fragments/72073-service_facts-aix-src.yml
Normal file
2
changelogs/fragments/72073-service_facts-aix-src.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- service_facts - return service state information on AIX.
|
|
@ -16,7 +16,7 @@ short_description: Return service state information as fact data
|
||||||
description:
|
description:
|
||||||
- Return service state information as fact data for various service management utilities
|
- Return service state information as fact data for various service management utilities
|
||||||
version_added: "2.5"
|
version_added: "2.5"
|
||||||
requirements: ["Any of the following supported init systems: systemd, sysv, upstart"]
|
requirements: ["Any of the following supported init systems: systemd, sysv, upstart, AIX SRC"]
|
||||||
|
|
||||||
notes:
|
notes:
|
||||||
- When accessing the C(ansible_facts.services) facts collected by this module,
|
- When accessing the C(ansible_facts.services) facts collected by this module,
|
||||||
|
@ -25,6 +25,7 @@ notes:
|
||||||
C(ansible_facts.services.zuul-gateway). It is instead recommended to
|
C(ansible_facts.services.zuul-gateway). It is instead recommended to
|
||||||
using the string value of the service name as the key in order to obtain
|
using the string value of the service name as the key in order to obtain
|
||||||
the fact data value like C(ansible_facts.services['zuul-gateway'])
|
the fact data value like C(ansible_facts.services['zuul-gateway'])
|
||||||
|
- AIX SRC was added in version 2.11.
|
||||||
|
|
||||||
author:
|
author:
|
||||||
- Adam Miller (@maxamillion)
|
- Adam Miller (@maxamillion)
|
||||||
|
@ -53,7 +54,7 @@ ansible_facts:
|
||||||
source:
|
source:
|
||||||
description:
|
description:
|
||||||
- Init system of the service.
|
- Init system of the service.
|
||||||
- One of C(systemd), C(sysv), C(upstart).
|
- One of C(systemd), C(sysv), C(upstart), C(src).
|
||||||
returned: always
|
returned: always
|
||||||
type: str
|
type: str
|
||||||
sample: sysv
|
sample: sysv
|
||||||
|
@ -79,6 +80,7 @@ ansible_facts:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
import platform
|
||||||
import re
|
import re
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
|
@ -230,10 +232,37 @@ class SystemctlScanService(BaseService):
|
||||||
return services
|
return services
|
||||||
|
|
||||||
|
|
||||||
|
class AIXScanService(BaseService):
|
||||||
|
|
||||||
|
def gather_services(self):
|
||||||
|
services = {}
|
||||||
|
if platform.system() != 'AIX':
|
||||||
|
return None
|
||||||
|
lssrc_path = self.module.get_bin_path("lssrc")
|
||||||
|
if lssrc_path is None:
|
||||||
|
return None
|
||||||
|
rc, stdout, stderr = self.module.run_command("%s -a" % lssrc_path)
|
||||||
|
for line in stdout.split('\n'):
|
||||||
|
line_data = line.split()
|
||||||
|
if len(line_data) < 2:
|
||||||
|
continue # Skipping because we expected more data
|
||||||
|
if line_data[0] == "Subsystem":
|
||||||
|
continue # Skip header
|
||||||
|
service_name = line_data[0]
|
||||||
|
if line_data[-1] == "active":
|
||||||
|
service_state = "running"
|
||||||
|
elif line_data[-1] == "inoperative":
|
||||||
|
service_state = "stopped"
|
||||||
|
else:
|
||||||
|
service_state = "unknown"
|
||||||
|
services[service_name] = {"name": service_name, "state": service_state, "source": "src"}
|
||||||
|
return services
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
module = AnsibleModule(argument_spec=dict(), supports_check_mode=True)
|
module = AnsibleModule(argument_spec=dict(), supports_check_mode=True)
|
||||||
module.run_command_environ_update = dict(LANG="C", LC_ALL="C")
|
module.run_command_environ_update = dict(LANG="C", LC_ALL="C")
|
||||||
service_modules = (ServiceScanService, SystemctlScanService)
|
service_modules = (ServiceScanService, SystemctlScanService, AIXScanService)
|
||||||
all_services = {}
|
all_services = {}
|
||||||
incomplete_warning = False
|
incomplete_warning = False
|
||||||
for svc_module in service_modules:
|
for svc_module in service_modules:
|
||||||
|
|
126
test/units/modules/test_service_facts.py
Normal file
126
test/units/modules/test_service_facts.py
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2020 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
from units.compat import unittest
|
||||||
|
from units.compat.mock import patch
|
||||||
|
|
||||||
|
from ansible.module_utils import basic
|
||||||
|
from ansible.modules.service_facts import AIXScanService
|
||||||
|
|
||||||
|
|
||||||
|
# AIX # lssrc -a
|
||||||
|
LSSRC_OUTPUT = """
|
||||||
|
Subsystem Group PID Status
|
||||||
|
sendmail mail 5243302 active
|
||||||
|
syslogd ras 5636528 active
|
||||||
|
portmap portmap 5177768 active
|
||||||
|
snmpd tcpip 5308844 active
|
||||||
|
hostmibd tcpip 5374380 active
|
||||||
|
snmpmibd tcpip 5439918 active
|
||||||
|
aixmibd tcpip 5505456 active
|
||||||
|
nimsh nimclient 5571004 active
|
||||||
|
aso 6029758 active
|
||||||
|
biod nfs 6357464 active
|
||||||
|
nfsd nfs 5701906 active
|
||||||
|
rpc.mountd nfs 6488534 active
|
||||||
|
rpc.statd nfs 7209216 active
|
||||||
|
rpc.lockd nfs 7274988 active
|
||||||
|
qdaemon spooler 6816222 active
|
||||||
|
writesrv spooler 6685150 active
|
||||||
|
clcomd caa 7471600 active
|
||||||
|
sshd ssh 7602674 active
|
||||||
|
pfcdaemon 7012860 active
|
||||||
|
ctrmc rsct 6947312 active
|
||||||
|
IBM.HostRM rsct_rm 14418376 active
|
||||||
|
IBM.ConfigRM rsct_rm 6160674 active
|
||||||
|
IBM.DRM rsct_rm 14680550 active
|
||||||
|
IBM.MgmtDomainRM rsct_rm 14090676 active
|
||||||
|
IBM.ServiceRM rsct_rm 13828542 active
|
||||||
|
cthats cthats 13959668 active
|
||||||
|
cthags cthags 14025054 active
|
||||||
|
IBM.StorageRM rsct_rm 12255706 active
|
||||||
|
inetd tcpip 12517828 active
|
||||||
|
lpd spooler inoperative
|
||||||
|
keyserv keyserv inoperative
|
||||||
|
ypbind yp inoperative
|
||||||
|
gsclvmd inoperative
|
||||||
|
cdromd inoperative
|
||||||
|
ndpd-host tcpip inoperative
|
||||||
|
ndpd-router tcpip inoperative
|
||||||
|
netcd netcd inoperative
|
||||||
|
tftpd tcpip inoperative
|
||||||
|
routed tcpip inoperative
|
||||||
|
mrouted tcpip inoperative
|
||||||
|
rsvpd qos inoperative
|
||||||
|
policyd qos inoperative
|
||||||
|
timed tcpip inoperative
|
||||||
|
iptrace tcpip inoperative
|
||||||
|
dpid2 tcpip inoperative
|
||||||
|
rwhod tcpip inoperative
|
||||||
|
pxed tcpip inoperative
|
||||||
|
binld tcpip inoperative
|
||||||
|
xntpd tcpip inoperative
|
||||||
|
gated tcpip inoperative
|
||||||
|
dhcpcd tcpip inoperative
|
||||||
|
dhcpcd6 tcpip inoperative
|
||||||
|
dhcpsd tcpip inoperative
|
||||||
|
dhcpsdv6 tcpip inoperative
|
||||||
|
dhcprd tcpip inoperative
|
||||||
|
dfpd tcpip inoperative
|
||||||
|
named tcpip inoperative
|
||||||
|
automountd autofs inoperative
|
||||||
|
nfsrgyd nfs inoperative
|
||||||
|
gssd nfs inoperative
|
||||||
|
cpsd ike inoperative
|
||||||
|
tmd ike inoperative
|
||||||
|
isakmpd inoperative
|
||||||
|
ikev2d inoperative
|
||||||
|
iked ike inoperative
|
||||||
|
clconfd caa inoperative
|
||||||
|
ksys_vmmon inoperative
|
||||||
|
nimhttp inoperative
|
||||||
|
IBM.SRVPROXY ibmsrv inoperative
|
||||||
|
ctcas rsct inoperative
|
||||||
|
IBM.ERRM rsct_rm inoperative
|
||||||
|
IBM.AuditRM rsct_rm inoperative
|
||||||
|
isnstgtd isnstgtd inoperative
|
||||||
|
IBM.LPRM rsct_rm inoperative
|
||||||
|
cthagsglsm cthags inoperative
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class TestAIXScanService(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.mock1 = patch.object(basic.AnsibleModule, 'get_bin_path', return_value='/usr/sbin/lssrc')
|
||||||
|
self.mock1.start()
|
||||||
|
self.addCleanup(self.mock1.stop)
|
||||||
|
self.mock2 = patch.object(basic.AnsibleModule, 'run_command', return_value=(0, LSSRC_OUTPUT, ''))
|
||||||
|
self.mock2.start()
|
||||||
|
self.addCleanup(self.mock2.stop)
|
||||||
|
self.mock3 = patch('platform.system', return_value='AIX')
|
||||||
|
self.mock3.start()
|
||||||
|
self.addCleanup(self.mock3.stop)
|
||||||
|
|
||||||
|
def test_gather_services(self):
|
||||||
|
svcmod = AIXScanService(basic.AnsibleModule)
|
||||||
|
result = svcmod.gather_services()
|
||||||
|
|
||||||
|
self.assertIsInstance(result, dict)
|
||||||
|
|
||||||
|
self.assertIn('IBM.HostRM', result)
|
||||||
|
self.assertEqual(result['IBM.HostRM'], {
|
||||||
|
'name': 'IBM.HostRM',
|
||||||
|
'source': 'src',
|
||||||
|
'state': 'running',
|
||||||
|
})
|
||||||
|
self.assertIn('IBM.AuditRM', result)
|
||||||
|
self.assertEqual(result['IBM.AuditRM'], {
|
||||||
|
'name': 'IBM.AuditRM',
|
||||||
|
'source': 'src',
|
||||||
|
'state': 'stopped',
|
||||||
|
})
|
Loading…
Reference in a new issue