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:
dberg1 2020-10-13 17:28:59 +02:00 committed by GitHub
parent caba47dd3f
commit cdf62edc65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 160 additions and 3 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- service_facts - return service state information on AIX.

View file

@ -16,7 +16,7 @@ short_description: Return service state information as fact data
description:
- Return service state information as fact data for various service management utilities
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:
- 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
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'])
- AIX SRC was added in version 2.11.
author:
- Adam Miller (@maxamillion)
@ -53,7 +54,7 @@ ansible_facts:
source:
description:
- 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
type: str
sample: sysv
@ -79,6 +80,7 @@ ansible_facts:
'''
import platform
import re
from ansible.module_utils.basic import AnsibleModule
@ -230,10 +232,37 @@ class SystemctlScanService(BaseService):
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():
module = AnsibleModule(argument_spec=dict(), supports_check_mode=True)
module.run_command_environ_update = dict(LANG="C", LC_ALL="C")
service_modules = (ServiceScanService, SystemctlScanService)
service_modules = (ServiceScanService, SystemctlScanService, AIXScanService)
all_services = {}
incomplete_warning = False
for svc_module in service_modules:

View 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',
})