1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Make changes proposed during review of restrict fact gathering feature:

* Make documentation examples into code blocks
* Make code to call the subsets more general.
* Made min subset always execute (cannot disable it).
* Use a passed in modules parameter rather than global modules.  This is needed for ziploader
* Remove unneeded __init__()
* Remove uneeded multiple inheritance from a base class
* gather_facts is now a list type
This commit is contained in:
Toshio Kuratomi 2016-03-14 09:45:28 -07:00
parent d665911bab
commit 5a1e35224b
3 changed files with 131 additions and 187 deletions

View file

@ -355,7 +355,7 @@ This option can be useful for those wishing to save fact gathering time. Both 's
.. versionadded:: 2.1
You can specify a subset of gathered facts using the following options:
You can specify a subset of gathered facts using the following options::
gather_subset = all
@ -367,7 +367,7 @@ You can specify a subset of gathered facts using the following options:
You can combine them using comma separated list (ex: min,network,virtual)
You can also disable puppet facter or chef ohai facts collection using following options:
You can also disable puppet facter or chef ohai facts collection using following options::
ignore_ohai = True
ignore_facter = True

View file

@ -159,11 +159,9 @@ class Facts(object):
{ 'path' : '/usr/local/sbin/pkg', 'name' : 'pkgng' },
]
# Allowed fact subset for gather_subset options
ALLOWED_FACT_SUBSET = frozenset([ 'all', 'min', 'network', 'hardware', 'virtual' ])
def __init__(self, load_on_init=True):
def __init__(self, module, load_on_init=True):
self.module = module
self.facts = {}
if load_on_init:
@ -218,14 +216,14 @@ class Facts(object):
elif self.facts['system'] == 'AIX':
# Attempt to use getconf to figure out architecture
# fall back to bootinfo if needed
if module.get_bin_path('getconf'):
rc, out, err = module.run_command([module.get_bin_path('getconf'),
'MACHINE_ARCHITECTURE'])
getconf_bin = self.module.get_bin_path('getconf')
if getconf_bin:
rc, out, err = self.module.run_command([getconf_bin, 'MACHINE_ARCHITECTURE'])
data = out.split('\n')
self.facts['architecture'] = data[0]
else:
rc, out, err = module.run_command([module.get_bin_path('bootinfo'),
'-p'])
bootinfo_bin = self.module.get_bin_path('bootinfo')
rc, out, err = self.module.run_command([bootinfo_bin, '-p'])
data = out.split('\n')
self.facts['architecture'] = data[0]
elif self.facts['system'] == 'OpenBSD':
@ -233,7 +231,7 @@ class Facts(object):
def get_local_facts(self):
fact_path = module.params.get('fact_path', None)
fact_path = self.module.params.get('fact_path', None)
if not fact_path or not os.path.exists(fact_path):
return
@ -246,7 +244,7 @@ class Facts(object):
# try to read it as json first
# if that fails read it with ConfigParser
# if that fails, skip it
rc, out, err = module.run_command(fn)
rc, out, err = self.module.run_command(fn)
else:
out = get_file_content(fn, default='')
@ -297,20 +295,20 @@ class Facts(object):
# as it's much cleaner than this massive if-else
if self.facts['system'] == 'AIX':
self.facts['distribution'] = 'AIX'
rc, out, err = module.run_command("/usr/bin/oslevel")
rc, out, err = self.module.run_command("/usr/bin/oslevel")
data = out.split('.')
self.facts['distribution_version'] = data[0]
self.facts['distribution_release'] = data[1]
elif self.facts['system'] == 'HP-UX':
self.facts['distribution'] = 'HP-UX'
rc, out, err = module.run_command("/usr/sbin/swlist |egrep 'HPUX.*OE.*[AB].[0-9]+\.[0-9]+'", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/sbin/swlist |egrep 'HPUX.*OE.*[AB].[0-9]+\.[0-9]+'", use_unsafe_shell=True)
data = re.search('HPUX.*OE.*([AB].[0-9]+\.[0-9]+)\.([0-9]+).*', out)
if data:
self.facts['distribution_version'] = data.groups()[0]
self.facts['distribution_release'] = data.groups()[1]
elif self.facts['system'] == 'Darwin':
self.facts['distribution'] = 'MacOSX'
rc, out, err = module.run_command("/usr/bin/sw_vers -productVersion")
rc, out, err = self.module.run_command("/usr/bin/sw_vers -productVersion")
data = out.split()[-1]
self.facts['distribution_version'] = data
elif self.facts['system'] == 'FreeBSD':
@ -324,7 +322,7 @@ class Facts(object):
elif self.facts['system'] == 'OpenBSD':
self.facts['distribution'] = 'OpenBSD'
self.facts['distribution_release'] = platform.release()
rc, out, err = module.run_command("/sbin/sysctl -n kern.version")
rc, out, err = self.module.run_command("/sbin/sysctl -n kern.version")
match = re.match('OpenBSD\s[0-9]+.[0-9]+-(\S+)\s.*', out)
if match:
self.facts['distribution_version'] = match.groups()[0]
@ -414,7 +412,7 @@ class Facts(object):
self.facts['distribution_release'] = ora_prefix + data
break
uname_rc, uname_out, uname_err = module.run_command(['uname', '-v'])
uname_rc, uname_out, uname_err = self.module.run_command(['uname', '-v'])
distribution_version = None
if 'SmartOS' in data:
self.facts['distribution'] = 'SmartOS'
@ -580,7 +578,7 @@ class Facts(object):
# try various forms of querying pid 1
proc_1 = get_file_content('/proc/1/comm')
if proc_1 is None:
rc, proc_1, err = module.run_command("ps -p 1 -o comm|tail -n 1", use_unsafe_shell=True)
rc, proc_1, err = self.module.run_command("ps -p 1 -o comm|tail -n 1", use_unsafe_shell=True)
else:
proc_1 = os.path.basename(proc_1)
@ -613,7 +611,7 @@ class Facts(object):
elif self.facts['system'] == 'Linux':
if self._check_systemd():
self.facts['service_mgr'] = 'systemd'
elif module.get_bin_path('initctl') and os.path.exists("/etc/init/"):
elif self.module.get_bin_path('initctl') and os.path.exists("/etc/init/"):
self.facts['service_mgr'] = 'upstart'
elif os.path.realpath('/sbin/rc') == '/sbin/openrc':
self.facts['service_mgr'] = 'openrc'
@ -625,9 +623,9 @@ class Facts(object):
self.facts['service_mgr'] = 'service'
def get_lsb_facts(self):
lsb_path = module.get_bin_path('lsb_release')
lsb_path = self.module.get_bin_path('lsb_release')
if lsb_path:
rc, out, err = module.run_command([lsb_path, "-a"])
rc, out, err = self.module.run_command([lsb_path, "-a"])
if rc == 0:
self.facts['lsb'] = {}
for line in out.split('\n'):
@ -735,7 +733,7 @@ class Facts(object):
def _check_systemd(self):
# tools must be installed
if module.get_bin_path('systemctl'):
if self.module.get_bin_path('systemctl'):
# this should show if systemd is the boot init system, if checking init faild to mark as systemd
# these mirror systemd's own sd_boot test http://www.freedesktop.org/software/systemd/man/sd_booted.html
@ -845,9 +843,6 @@ class Hardware(Facts):
subclass = sc
return super(cls, subclass).__new__(subclass, *arguments, **keyword)
def __init__(self):
Facts.__init__(self)
def populate(self):
return self.facts
@ -872,9 +867,6 @@ class LinuxHardware(Hardware):
# Now we have all of these in a dict structure
MEMORY_FACTS = ORIGINAL_MEMORY_FACTS.union(('Buffers', 'Cached', 'SwapCached'))
def __init__(self):
Hardware.__init__(self)
def populate(self):
self.get_cpu_facts()
self.get_memory_facts()
@ -1058,7 +1050,7 @@ class LinuxHardware(Hardware):
else:
# Fall back to using dmidecode, if available
dmi_bin = module.get_bin_path('dmidecode')
dmi_bin = self.module.get_bin_path('dmidecode')
DMI_DICT = {
'bios_date': 'bios-release-date',
'bios_version': 'bios-version',
@ -1071,7 +1063,7 @@ class LinuxHardware(Hardware):
}
for (k, v) in DMI_DICT.items():
if dmi_bin is not None:
(rc, out, err) = module.run_command('%s -s %s' % (dmi_bin, v))
(rc, out, err) = self.module.run_command('%s -s %s' % (dmi_bin, v))
if rc == 0:
# Strip out commented lines (specific dmidecode output)
thisvalue = ''.join([ line for line in out.split('\n') if not line.startswith('#') ])
@ -1100,9 +1092,9 @@ class LinuxHardware(Hardware):
uuid = uuids[fields[0]]
else:
uuid = 'NA'
lsblkPath = module.get_bin_path("lsblk")
lsblkPath = self.module.get_bin_path("lsblk")
if lsblkPath:
rc, out, err = module.run_command("%s -ln --output UUID %s" % (lsblkPath, fields[0]), use_unsafe_shell=True)
rc, out, err = self.module.run_command("%s -ln --output UUID %s" % (lsblkPath, fields[0]), use_unsafe_shell=True)
if rc == 0:
uuid = out.strip()
@ -1121,9 +1113,9 @@ class LinuxHardware(Hardware):
def get_device_facts(self):
self.facts['devices'] = {}
lspci = module.get_bin_path('lspci')
lspci = self.module.get_bin_path('lspci')
if lspci:
rc, pcidata, err = module.run_command([lspci, '-D'])
rc, pcidata, err = self.module.run_command([lspci, '-D'])
else:
pcidata = None
@ -1176,7 +1168,7 @@ class LinuxHardware(Hardware):
part['sectorsize'] = get_file_content(part_sysdir + "/queue/logical_block_size")
if not part['sectorsize']:
part['sectorsize'] = get_file_content(part_sysdir + "/queue/hw_sector_size",512)
part['size'] = module.pretty_bytes((float(part['sectors']) * float(part['sectorsize'])))
part['size'] = self.module.pretty_bytes((float(part['sectors']) * float(part['sectorsize'])))
d['partitions'][partname] = part
d['rotational'] = get_file_content(sysdir + "/queue/rotational")
@ -1193,7 +1185,7 @@ class LinuxHardware(Hardware):
d['sectorsize'] = get_file_content(sysdir + "/queue/logical_block_size")
if not d['sectorsize']:
d['sectorsize'] = get_file_content(sysdir + "/queue/hw_sector_size",512)
d['size'] = module.pretty_bytes(float(d['sectors']) * float(d['sectorsize']))
d['size'] = self.module.pretty_bytes(float(d['sectors']) * float(d['sectorsize']))
d['host'] = ""
@ -1228,14 +1220,14 @@ class LinuxHardware(Hardware):
def get_lvm_facts(self):
""" Get LVM Facts if running as root and lvm utils are available """
if os.getuid() == 0 and module.get_bin_path('vgs'):
if os.getuid() == 0 and self.module.get_bin_path('vgs'):
lvm_util_options = '--noheadings --nosuffix --units g'
vgs_path = module.get_bin_path('vgs')
vgs_path = self.module.get_bin_path('vgs')
#vgs fields: VG #PV #LV #SN Attr VSize VFree
vgs={}
if vgs_path:
rc, vg_lines, err = module.run_command( '%s %s' % (vgs_path, lvm_util_options))
rc, vg_lines, err = self.module.run_command( '%s %s' % (vgs_path, lvm_util_options))
for vg_line in vg_lines.splitlines():
items = vg_line.split()
vgs[items[0]] = {'size_g':items[-2],
@ -1243,12 +1235,12 @@ class LinuxHardware(Hardware):
'num_lvs': items[2],
'num_pvs': items[1]}
lvs_path = module.get_bin_path('lvs')
lvs_path = self.module.get_bin_path('lvs')
#lvs fields:
#LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert
lvs = {}
if lvs_path:
rc, lv_lines, err = module.run_command( '%s %s' % (lvs_path, lvm_util_options))
rc, lv_lines, err = self.module.run_command( '%s %s' % (lvs_path, lvm_util_options))
for lv_line in lv_lines.splitlines():
items = lv_line.split()
lvs[items[0]] = {'size_g': items[3], 'vg': items[1]}
@ -1263,9 +1255,6 @@ class SunOSHardware(Hardware):
"""
platform = 'SunOS'
def __init__(self):
Hardware.__init__(self)
def populate(self):
self.get_cpu_facts()
self.get_memory_facts()
@ -1278,7 +1267,7 @@ class SunOSHardware(Hardware):
def get_cpu_facts(self):
physid = 0
sockets = {}
rc, out, err = module.run_command("/usr/bin/kstat cpu_info")
rc, out, err = self.module.run_command("/usr/bin/kstat cpu_info")
self.facts['processor'] = []
for line in out.split('\n'):
if len(line) < 1:
@ -1319,11 +1308,11 @@ class SunOSHardware(Hardware):
self.facts['processor_count'] = len(self.facts['processor'])
def get_memory_facts(self):
rc, out, err = module.run_command(["/usr/sbin/prtconf"])
rc, out, err = self.module.run_command(["/usr/sbin/prtconf"])
for line in out.split('\n'):
if 'Memory size' in line:
self.facts['memtotal_mb'] = line.split()[2]
rc, out, err = module.run_command("/usr/sbin/swap -s")
rc, out, err = self.module.run_command("/usr/sbin/swap -s")
allocated = long(out.split()[1][:-1])
reserved = long(out.split()[5][:-1])
used = long(out.split()[8][:-1])
@ -1362,9 +1351,6 @@ class OpenBSDHardware(Hardware):
platform = 'OpenBSD'
DMESG_BOOT = '/var/run/dmesg.boot'
def __init__(self):
Hardware.__init__(self)
def populate(self):
self.sysctl = self.get_sysctl()
self.get_memory_facts()
@ -1374,7 +1360,7 @@ class OpenBSDHardware(Hardware):
return self.facts
def get_sysctl(self):
rc, out, err = module.run_command(["/sbin/sysctl", "hw"])
rc, out, err = self.module.run_command(["/sbin/sysctl", "hw"])
if rc != 0:
return dict()
sysctl = dict()
@ -1403,7 +1389,7 @@ class OpenBSDHardware(Hardware):
# procs memory page disks traps cpu
# r b w avm fre flt re pi po fr sr wd0 fd0 int sys cs us sy id
# 0 0 0 47512 28160 51 0 0 0 0 0 1 0 116 89 17 0 1 99
rc, out, err = module.run_command("/usr/bin/vmstat")
rc, out, err = self.module.run_command("/usr/bin/vmstat")
if rc == 0:
self.facts['memfree_mb'] = long(out.splitlines()[-1].split()[4]) / 1024
self.facts['memtotal_mb'] = long(self.sysctl['hw.usermem']) / 1024 / 1024
@ -1412,7 +1398,7 @@ class OpenBSDHardware(Hardware):
# total: 69268 1K-blocks allocated, 0 used, 69268 available
# And for older OpenBSD:
# total: 69268k bytes allocated = 0k used, 69268k available
rc, out, err = module.run_command("/sbin/swapctl -sk")
rc, out, err = self.module.run_command("/sbin/swapctl -sk")
if rc == 0:
swaptrans = maketrans(' ', ' ')
data = out.split()
@ -1423,7 +1409,7 @@ class OpenBSDHardware(Hardware):
processor = []
dmesg_boot = get_file_content(OpenBSDHardware.DMESG_BOOT)
if not dmesg_boot:
rc, dmesg_boot, err = module.run_command("/sbin/dmesg")
rc, dmesg_boot, err = self.module.run_command("/sbin/dmesg")
i = 0
for line in dmesg_boot.splitlines():
if line.split(' ', 1)[0] == 'cpu%i:' % i:
@ -1455,9 +1441,6 @@ class FreeBSDHardware(Hardware):
platform = 'FreeBSD'
DMESG_BOOT = '/var/run/dmesg.boot'
def __init__(self):
Hardware.__init__(self)
def populate(self):
self.get_cpu_facts()
self.get_memory_facts()
@ -1471,12 +1454,12 @@ class FreeBSDHardware(Hardware):
def get_cpu_facts(self):
self.facts['processor'] = []
rc, out, err = module.run_command("/sbin/sysctl -n hw.ncpu")
rc, out, err = self.module.run_command("/sbin/sysctl -n hw.ncpu")
self.facts['processor_count'] = out.strip()
dmesg_boot = get_file_content(FreeBSDHardware.DMESG_BOOT)
if not dmesg_boot:
rc, dmesg_boot, err = module.run_command("/sbin/dmesg")
rc, dmesg_boot, err = self.module.run_command("/sbin/dmesg")
for line in dmesg_boot.split('\n'):
if 'CPU:' in line:
cpu = re.sub(r'CPU:\s+', r"", line)
@ -1486,7 +1469,7 @@ class FreeBSDHardware(Hardware):
def get_memory_facts(self):
rc, out, err = module.run_command("/sbin/sysctl vm.stats")
rc, out, err = self.module.run_command("/sbin/sysctl vm.stats")
for line in out.split('\n'):
data = line.split()
if 'vm.stats.vm.v_page_size' in line:
@ -1501,7 +1484,7 @@ class FreeBSDHardware(Hardware):
# Device 1M-blocks Used Avail Capacity
# /dev/ada0p3 314368 0 314368 0%
#
rc, out, err = module.run_command("/usr/sbin/swapinfo -k")
rc, out, err = self.module.run_command("/usr/sbin/swapinfo -k")
lines = out.split('\n')
if len(lines[-1]) == 0:
lines.pop()
@ -1525,7 +1508,7 @@ class FreeBSDHardware(Hardware):
def get_device_facts(self):
sysdir = '/dev'
self.facts['devices'] = {}
drives = re.compile('(ada?\d+|da\d+|a?cd\d+)') #TODO: rc, disks, err = module.run_command("/sbin/sysctl kern.disks")
drives = re.compile('(ada?\d+|da\d+|a?cd\d+)') #TODO: rc, disks, err = self.module.run_command("/sbin/sysctl kern.disks")
slices = re.compile('(ada?\d+s\d+\w*|da\d+s\d+\w*)')
if os.path.isdir(sysdir):
dirlist = sorted(os.listdir(sysdir))
@ -1543,7 +1526,7 @@ class FreeBSDHardware(Hardware):
Use dmidecode executable if available'''
# Fall back to using dmidecode, if available
dmi_bin = module.get_bin_path('dmidecode')
dmi_bin = self.module.get_bin_path('dmidecode')
DMI_DICT = dict(
bios_date='bios-release-date',
bios_version='bios-version',
@ -1556,7 +1539,7 @@ class FreeBSDHardware(Hardware):
)
for (k, v) in DMI_DICT.items():
if dmi_bin is not None:
(rc, out, err) = module.run_command('%s -s %s' % (dmi_bin, v))
(rc, out, err) = self.module.run_command('%s -s %s' % (dmi_bin, v))
if rc == 0:
# Strip out commented lines (specific dmidecode output)
self.facts[k] = ''.join([ line for line in out.split('\n') if not line.startswith('#') ])
@ -1587,9 +1570,6 @@ class NetBSDHardware(Hardware):
platform = 'NetBSD'
MEMORY_FACTS = ['MemTotal', 'SwapTotal', 'MemFree', 'SwapFree']
def __init__(self):
Hardware.__init__(self)
def populate(self):
self.get_cpu_facts()
self.get_memory_facts()
@ -1665,9 +1645,6 @@ class AIX(Hardware):
"""
platform = 'AIX'
def __init__(self):
Hardware.__init__(self)
def populate(self):
self.get_cpu_facts()
self.get_memory_facts()
@ -1678,7 +1655,7 @@ class AIX(Hardware):
self.facts['processor'] = []
rc, out, err = module.run_command("/usr/sbin/lsdev -Cc processor")
rc, out, err = self.module.run_command("/usr/sbin/lsdev -Cc processor")
if out:
i = 0
for line in out.split('\n'):
@ -1691,19 +1668,19 @@ class AIX(Hardware):
i += 1
self.facts['processor_count'] = int(i)
rc, out, err = module.run_command("/usr/sbin/lsattr -El " + cpudev + " -a type")
rc, out, err = self.module.run_command("/usr/sbin/lsattr -El " + cpudev + " -a type")
data = out.split(' ')
self.facts['processor'] = data[1]
rc, out, err = module.run_command("/usr/sbin/lsattr -El " + cpudev + " -a smt_threads")
rc, out, err = self.module.run_command("/usr/sbin/lsattr -El " + cpudev + " -a smt_threads")
data = out.split(' ')
self.facts['processor_cores'] = int(data[1])
def get_memory_facts(self):
pagesize = 4096
rc, out, err = module.run_command("/usr/bin/vmstat -v")
rc, out, err = self.module.run_command("/usr/bin/vmstat -v")
for line in out.split('\n'):
data = line.split()
if 'memory pages' in line:
@ -1716,7 +1693,7 @@ class AIX(Hardware):
# Device 1M-blocks Used Avail Capacity
# /dev/ada0p3 314368 0 314368 0%
#
rc, out, err = module.run_command("/usr/sbin/lsps -s")
rc, out, err = self.module.run_command("/usr/sbin/lsps -s")
if out:
lines = out.split('\n')
data = lines[1].split()
@ -1726,7 +1703,7 @@ class AIX(Hardware):
self.facts['swapfree_mb'] = long(swaptotal_mb * ( 100 - percused ) / 100)
def get_dmi_facts(self):
rc, out, err = module.run_command("/usr/sbin/lsattr -El sys0 -a fwversion")
rc, out, err = self.module.run_command("/usr/sbin/lsattr -El sys0 -a fwversion")
data = out.split()
self.facts['firmware_version'] = data[1].strip('IBM,')
@ -1746,9 +1723,6 @@ class HPUX(Hardware):
platform = 'HP-UX'
def __init__(self):
Hardware.__init__(self)
def populate(self):
self.get_cpu_facts()
self.get_memory_facts()
@ -1757,31 +1731,31 @@ class HPUX(Hardware):
def get_cpu_facts(self):
if self.facts['architecture'] == '9000/800':
rc, out, err = module.run_command("ioscan -FkCprocessor | wc -l", use_unsafe_shell=True)
rc, out, err = self.module.run_command("ioscan -FkCprocessor | wc -l", use_unsafe_shell=True)
self.facts['processor_count'] = int(out.strip())
#Working with machinfo mess
elif self.facts['architecture'] == 'ia64':
if self.facts['distribution_version'] == "B.11.23":
rc, out, err = module.run_command("/usr/contrib/bin/machinfo | grep 'Number of CPUs'", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo | grep 'Number of CPUs'", use_unsafe_shell=True)
self.facts['processor_count'] = int(out.strip().split('=')[1])
rc, out, err = module.run_command("/usr/contrib/bin/machinfo | grep 'processor family'", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo | grep 'processor family'", use_unsafe_shell=True)
self.facts['processor'] = re.search('.*(Intel.*)', out).groups()[0].strip()
rc, out, err = module.run_command("ioscan -FkCprocessor | wc -l", use_unsafe_shell=True)
rc, out, err = self.module.run_command("ioscan -FkCprocessor | wc -l", use_unsafe_shell=True)
self.facts['processor_cores'] = int(out.strip())
if self.facts['distribution_version'] == "B.11.31":
#if machinfo return cores strings release B.11.31 > 1204
rc, out, err = module.run_command("/usr/contrib/bin/machinfo | grep core | wc -l", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo | grep core | wc -l", use_unsafe_shell=True)
if out.strip()== '0':
rc, out, err = module.run_command("/usr/contrib/bin/machinfo | grep Intel", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo | grep Intel", use_unsafe_shell=True)
self.facts['processor_count'] = int(out.strip().split(" ")[0])
#If hyperthreading is active divide cores by 2
rc, out, err = module.run_command("/usr/sbin/psrset | grep LCPU", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/sbin/psrset | grep LCPU", use_unsafe_shell=True)
data = re.sub(' +',' ',out).strip().split(' ')
if len(data) == 1:
hyperthreading = 'OFF'
else:
hyperthreading = data[1]
rc, out, err = module.run_command("/usr/contrib/bin/machinfo | grep logical", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo | grep logical", use_unsafe_shell=True)
data = out.strip().split(" ")
if hyperthreading == 'ON':
self.facts['processor_cores'] = int(data[0])/2
@ -1790,54 +1764,54 @@ class HPUX(Hardware):
self.facts['processor_cores'] = self.facts['processor_count']
else:
self.facts['processor_cores'] = int(data[0])
rc, out, err = module.run_command("/usr/contrib/bin/machinfo | grep Intel |cut -d' ' -f4-", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo | grep Intel |cut -d' ' -f4-", use_unsafe_shell=True)
self.facts['processor'] = out.strip()
else:
rc, out, err = module.run_command("/usr/contrib/bin/machinfo | egrep 'socket[s]?$' | tail -1", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo | egrep 'socket[s]?$' | tail -1", use_unsafe_shell=True)
self.facts['processor_count'] = int(out.strip().split(" ")[0])
rc, out, err = module.run_command("/usr/contrib/bin/machinfo | grep -e '[0-9] core' | tail -1", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo | grep -e '[0-9] core' | tail -1", use_unsafe_shell=True)
self.facts['processor_cores'] = int(out.strip().split(" ")[0])
rc, out, err = module.run_command("/usr/contrib/bin/machinfo | grep Intel", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo | grep Intel", use_unsafe_shell=True)
self.facts['processor'] = out.strip()
def get_memory_facts(self):
pagesize = 4096
rc, out, err = module.run_command("/usr/bin/vmstat | tail -1", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/bin/vmstat | tail -1", use_unsafe_shell=True)
data = int(re.sub(' +',' ',out).split(' ')[5].strip())
self.facts['memfree_mb'] = pagesize * data / 1024 / 1024
if self.facts['architecture'] == '9000/800':
try:
rc, out, err = module.run_command("grep Physical /var/adm/syslog/syslog.log")
rc, out, err = self.module.run_command("grep Physical /var/adm/syslog/syslog.log")
data = re.search('.*Physical: ([0-9]*) Kbytes.*',out).groups()[0].strip()
self.facts['memtotal_mb'] = int(data) / 1024
except AttributeError:
#For systems where memory details aren't sent to syslog or the log has rotated, use parsed
#adb output. Unfortunately /dev/kmem doesn't have world-read, so this only works as root.
if os.access("/dev/kmem", os.R_OK):
rc, out, err = module.run_command("echo 'phys_mem_pages/D' | adb -k /stand/vmunix /dev/kmem | tail -1 | awk '{print $2}'", use_unsafe_shell=True)
rc, out, err = self.module.run_command("echo 'phys_mem_pages/D' | adb -k /stand/vmunix /dev/kmem | tail -1 | awk '{print $2}'", use_unsafe_shell=True)
if not err:
data = out
self.facts['memtotal_mb'] = int(data) / 256
else:
rc, out, err = module.run_command("/usr/contrib/bin/machinfo | grep Memory", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo | grep Memory", use_unsafe_shell=True)
data = re.search('Memory[\ :=]*([0-9]*).*MB.*',out).groups()[0].strip()
self.facts['memtotal_mb'] = int(data)
rc, out, err = module.run_command("/usr/sbin/swapinfo -m -d -f -q")
rc, out, err = self.module.run_command("/usr/sbin/swapinfo -m -d -f -q")
self.facts['swaptotal_mb'] = int(out.strip())
rc, out, err = module.run_command("/usr/sbin/swapinfo -m -d -f | egrep '^dev|^fs'", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/sbin/swapinfo -m -d -f | egrep '^dev|^fs'", use_unsafe_shell=True)
swap = 0
for line in out.strip().split('\n'):
swap += int(re.sub(' +',' ',line).split(' ')[3].strip())
self.facts['swapfree_mb'] = swap
def get_hw_facts(self):
rc, out, err = module.run_command("model")
rc, out, err = self.module.run_command("model")
self.facts['model'] = out.strip()
if self.facts['architecture'] == 'ia64':
separator = ':'
if self.facts['distribution_version'] == "B.11.23":
separator = '='
rc, out, err = module.run_command("/usr/contrib/bin/machinfo |grep -i 'Firmware revision' | grep -v BMC", use_unsafe_shell=True)
rc, out, err = self.module.run_command("/usr/contrib/bin/machinfo |grep -i 'Firmware revision' | grep -v BMC", use_unsafe_shell=True)
self.facts['firmware_version'] = out.split(separator)[1].strip()
@ -1854,9 +1828,6 @@ class Darwin(Hardware):
"""
platform = 'Darwin'
def __init__(self):
Hardware.__init__(self)
def populate(self):
self.sysctl = self.get_sysctl()
self.get_mac_facts()
@ -1865,7 +1836,7 @@ class Darwin(Hardware):
return self.facts
def get_sysctl(self):
rc, out, err = module.run_command(["/usr/sbin/sysctl", "hw", "machdep", "kern"])
rc, out, err = self.module.run_command(["/usr/sbin/sysctl", "hw", "machdep", "kern"])
if rc != 0:
return dict()
sysctl = dict()
@ -1876,7 +1847,7 @@ class Darwin(Hardware):
return sysctl
def get_system_profile(self):
rc, out, err = module.run_command(["/usr/sbin/system_profiler", "SPHardwareDataType"])
rc, out, err = self.module.run_command(["/usr/sbin/system_profiler", "SPHardwareDataType"])
if rc != 0:
return dict()
system_profile = dict()
@ -1887,7 +1858,7 @@ class Darwin(Hardware):
return system_profile
def get_mac_facts(self):
rc, out, err = module.run_command("sysctl hw.model")
rc, out, err = self.module.run_command("sysctl hw.model")
if rc == 0:
self.facts['model'] = out.splitlines()[-1].split()[1]
self.facts['osversion'] = self.sysctl['kern.osversion']
@ -1905,7 +1876,7 @@ class Darwin(Hardware):
def get_memory_facts(self):
self.facts['memtotal_mb'] = long(self.sysctl['hw.memsize']) / 1024 / 1024
rc, out, err = module.run_command("sysctl hw.usermem")
rc, out, err = self.module.run_command("sysctl hw.usermem")
if rc == 0:
self.facts['memfree_mb'] = long(out.splitlines()[-1].split()[1]) / 1024 / 1024
@ -1936,10 +1907,6 @@ class Network(Facts):
subclass = sc
return super(cls, subclass).__new__(subclass, *arguments, **keyword)
def __init__(self, module):
self.module = module
Facts.__init__(self)
def populate(self):
return self.facts
@ -1953,9 +1920,6 @@ class LinuxNetwork(Network):
"""
platform = 'Linux'
def __init__(self, module):
Network.__init__(self, module)
def populate(self):
ip_path = self.module.get_bin_path('ip')
if ip_path is None:
@ -1987,7 +1951,7 @@ class LinuxNetwork(Network):
continue
if v == 'v6' and not socket.has_ipv6:
continue
rc, out, err = module.run_command(command[v])
rc, out, err = self.module.run_command(command[v])
if not out:
# v6 routing may result in
# RTNETLINK answers: Invalid argument
@ -2147,7 +2111,7 @@ class LinuxNetwork(Network):
if not address == '::1':
ips['all_ipv6_addresses'].append(address)
ip_path = module.get_bin_path("ip")
ip_path = self.module.get_bin_path("ip")
args = [ip_path, 'addr', 'show', 'primary', device]
rc, stdout, stderr = self.module.run_command(args)
@ -2182,16 +2146,13 @@ class GenericBsdIfconfigNetwork(Network):
"""
platform = 'Generic_BSD_Ifconfig'
def __init__(self, module):
Network.__init__(self, module)
def populate(self):
ifconfig_path = module.get_bin_path('ifconfig')
ifconfig_path = self.module.get_bin_path('ifconfig')
if ifconfig_path is None:
return self.facts
route_path = module.get_bin_path('route')
route_path = self.module.get_bin_path('route')
if route_path is None:
return self.facts
@ -2230,7 +2191,7 @@ class GenericBsdIfconfigNetwork(Network):
if v == 'v6' and not socket.has_ipv6:
continue
rc, out, err = module.run_command(command[v])
rc, out, err = self.module.run_command(command[v])
if not out:
# v6 routing may result in
# RTNETLINK answers: Invalid argument
@ -2257,7 +2218,7 @@ class GenericBsdIfconfigNetwork(Network):
# FreeBSD, DragonflyBSD, NetBSD, OpenBSD and OS X all implicitly add '-a'
# when running the command 'ifconfig'.
# Solaris must explicitly run the command 'ifconfig -a'.
rc, out, err = module.run_command([ifconfig_path, ifconfig_options])
rc, out, err = self.module.run_command([ifconfig_path, ifconfig_options])
for line in out.split('\n'):
@ -2403,9 +2364,6 @@ class HPUXNetwork(Network):
"""
platform = 'HP-UX'
def __init__(self, module):
Network.__init__(self, module)
def populate(self):
netstat_path = self.module.get_bin_path('netstat')
if netstat_path is None:
@ -2418,7 +2376,7 @@ class HPUXNetwork(Network):
return self.facts
def get_default_interfaces(self):
rc, out, err = module.run_command("/usr/bin/netstat -nr")
rc, out, err = self.module.run_command("/usr/bin/netstat -nr")
lines = out.split('\n')
for line in lines:
words = line.split()
@ -2429,7 +2387,7 @@ class HPUXNetwork(Network):
def get_interfaces_info(self):
interfaces = {}
rc, out, err = module.run_command("/usr/bin/netstat -ni")
rc, out, err = self.module.run_command("/usr/bin/netstat -ni")
lines = out.split('\n')
for line in lines:
words = line.split()
@ -2445,7 +2403,7 @@ class HPUXNetwork(Network):
'address': address }
return interfaces
class DarwinNetwork(GenericBsdIfconfigNetwork, Network):
class DarwinNetwork(GenericBsdIfconfigNetwork):
"""
This is the Mac OS X/Darwin Network Class.
It uses the GenericBsdIfconfigNetwork unchanged
@ -2469,21 +2427,21 @@ class DarwinNetwork(GenericBsdIfconfigNetwork, Network):
current_if['media_options'] = self.get_options(words[3])
class FreeBSDNetwork(GenericBsdIfconfigNetwork, Network):
class FreeBSDNetwork(GenericBsdIfconfigNetwork):
"""
This is the FreeBSD Network Class.
It uses the GenericBsdIfconfigNetwork unchanged.
"""
platform = 'FreeBSD'
class DragonFlyNetwork(GenericBsdIfconfigNetwork, Network):
class DragonFlyNetwork(GenericBsdIfconfigNetwork):
"""
This is the DragonFly Network Class.
It uses the GenericBsdIfconfigNetwork unchanged.
"""
platform = 'DragonFly'
class AIXNetwork(GenericBsdIfconfigNetwork, Network):
class AIXNetwork(GenericBsdIfconfigNetwork):
"""
This is the AIX Network Class.
It uses the GenericBsdIfconfigNetwork unchanged.
@ -2491,9 +2449,9 @@ class AIXNetwork(GenericBsdIfconfigNetwork, Network):
platform = 'AIX'
def get_default_interfaces(self, route_path):
netstat_path = module.get_bin_path('netstat')
netstat_path = self.module.get_bin_path('netstat')
rc, out, err = module.run_command([netstat_path, '-nr'])
rc, out, err = self.module.run_command([netstat_path, '-nr'])
interface = dict(v4 = {}, v6 = {})
@ -2518,7 +2476,7 @@ class AIXNetwork(GenericBsdIfconfigNetwork, Network):
all_ipv4_addresses = [],
all_ipv6_addresses = [],
)
rc, out, err = module.run_command([ifconfig_path, ifconfig_options])
rc, out, err = self.module.run_command([ifconfig_path, ifconfig_options])
for line in out.split('\n'):
@ -2547,16 +2505,16 @@ class AIXNetwork(GenericBsdIfconfigNetwork, Network):
self.parse_inet6_line(words, current_if, ips)
else:
self.parse_unknown_line(words, current_if, ips)
uname_path = module.get_bin_path('uname')
uname_path = self.module.get_bin_path('uname')
if uname_path:
rc, out, err = module.run_command([uname_path, '-W'])
rc, out, err = self.module.run_command([uname_path, '-W'])
# don't bother with wpars it does not work
# zero means not in wpar
if not rc and out.split()[0] == '0':
if current_if['macaddress'] == 'unknown' and re.match('^en', current_if['device']):
entstat_path = module.get_bin_path('entstat')
entstat_path = self.module.get_bin_path('entstat')
if entstat_path:
rc, out, err = module.run_command([entstat_path, current_if['device'] ])
rc, out, err = self.module.run_command([entstat_path, current_if['device'] ])
if rc != 0:
break
for line in out.split('\n'):
@ -2571,9 +2529,9 @@ class AIXNetwork(GenericBsdIfconfigNetwork, Network):
current_if['type'] = 'ether'
# device must have mtu attribute in ODM
if 'mtu' not in current_if:
lsattr_path = module.get_bin_path('lsattr')
lsattr_path = self.module.get_bin_path('lsattr')
if lsattr_path:
rc, out, err = module.run_command([lsattr_path,'-El', current_if['device'] ])
rc, out, err = self.module.run_command([lsattr_path,'-El', current_if['device'] ])
if rc != 0:
break
for line in out.split('\n'):
@ -2591,7 +2549,7 @@ class AIXNetwork(GenericBsdIfconfigNetwork, Network):
current_if['macaddress'] = 'unknown' # will be overwritten later
return current_if
class OpenBSDNetwork(GenericBsdIfconfigNetwork, Network):
class OpenBSDNetwork(GenericBsdIfconfigNetwork):
"""
This is the OpenBSD Network Class.
It uses the GenericBsdIfconfigNetwork.
@ -2606,7 +2564,7 @@ class OpenBSDNetwork(GenericBsdIfconfigNetwork, Network):
def parse_lladdr_line(self, words, current_if, ips):
current_if['macaddress'] = words[1]
class SunOSNetwork(GenericBsdIfconfigNetwork, Network):
class SunOSNetwork(GenericBsdIfconfigNetwork):
"""
This is the SunOS Network Class.
It uses the GenericBsdIfconfigNetwork.
@ -2627,7 +2585,7 @@ class SunOSNetwork(GenericBsdIfconfigNetwork, Network):
all_ipv4_addresses = [],
all_ipv6_addresses = [],
)
rc, out, err = module.run_command([ifconfig_path, '-a'])
rc, out, err = self.module.run_command([ifconfig_path, '-a'])
for line in out.split('\n'):
@ -2711,9 +2669,6 @@ class Virtual(Facts):
subclass = sc
return super(cls, subclass).__new__(subclass, *arguments, **keyword)
def __init__(self):
Facts.__init__(self)
def populate(self):
return self.facts
@ -2725,9 +2680,6 @@ class LinuxVirtual(Virtual):
"""
platform = 'Linux'
def __init__(self):
Virtual.__init__(self)
def populate(self):
self.get_virtual_facts()
return self.facts
@ -2844,9 +2796,9 @@ class LinuxVirtual(Virtual):
self.facts['virtualization_type'] = 'powervm_lx86'
elif re.match('^vendor_id.*IBM/S390', line):
self.facts['virtualization_type'] = 'PR/SM'
lscpu = module.get_bin_path('lscpu')
lscpu = self.module.get_bin_path('lscpu')
if lscpu:
rc, out, err = module.run_command(["lscpu"])
rc, out, err = self.module.run_command(["lscpu"])
if rc == 0:
for line in out.split("\n"):
data = line.split(":", 1)
@ -2894,9 +2846,6 @@ class FreeBSDVirtual(Virtual):
"""
platform = 'FreeBSD'
def __init__(self):
Virtual.__init__(self)
def populate(self):
self.get_virtual_facts()
return self.facts
@ -2916,9 +2865,6 @@ class OpenBSDVirtual(Virtual):
"""
platform = 'OpenBSD'
def __init__(self):
Virtual.__init__(self)
def populate(self):
self.get_virtual_facts()
return self.facts
@ -2935,21 +2881,18 @@ class HPUXVirtual(Virtual):
"""
platform = 'HP-UX'
def __init__(self):
Virtual.__init__(self)
def populate(self):
self.get_virtual_facts()
return self.facts
def get_virtual_facts(self):
if os.path.exists('/usr/sbin/vecheck'):
rc, out, err = module.run_command("/usr/sbin/vecheck")
rc, out, err = self.module.run_command("/usr/sbin/vecheck")
if rc == 0:
self.facts['virtualization_type'] = 'guest'
self.facts['virtualization_role'] = 'HP vPar'
if os.path.exists('/opt/hpvm/bin/hpvminfo'):
rc, out, err = module.run_command("/opt/hpvm/bin/hpvminfo")
rc, out, err = self.module.run_command("/opt/hpvm/bin/hpvminfo")
if rc == 0 and re.match('.*Running.*HPVM vPar.*', out):
self.facts['virtualization_type'] = 'guest'
self.facts['virtualization_role'] = 'HPVM vPar'
@ -2960,7 +2903,7 @@ class HPUXVirtual(Virtual):
self.facts['virtualization_type'] = 'host'
self.facts['virtualization_role'] = 'HPVM'
if os.path.exists('/usr/sbin/parstatus'):
rc, out, err = module.run_command("/usr/sbin/parstatus")
rc, out, err = self.module.run_command("/usr/sbin/parstatus")
if rc == 0:
self.facts['virtualization_type'] = 'guest'
self.facts['virtualization_role'] = 'HP nPar'
@ -2975,15 +2918,12 @@ class SunOSVirtual(Virtual):
"""
platform = 'SunOS'
def __init__(self):
Virtual.__init__(self)
def populate(self):
self.get_virtual_facts()
return self.facts
def get_virtual_facts(self):
rc, out, err = module.run_command("/usr/sbin/prtdiag")
rc, out, err = self.module.run_command("/usr/sbin/prtdiag")
for line in out.split('\n'):
if 'VMware' in line:
self.facts['virtualization_type'] = 'vmware'
@ -2999,7 +2939,7 @@ class SunOSVirtual(Virtual):
self.facts['virtualization_role'] = 'guest'
# Check if it's a zone
if os.path.exists("/usr/bin/zonename"):
rc, out, err = module.run_command("/usr/bin/zonename")
rc, out, err = self.module.run_command("/usr/bin/zonename")
if out.rstrip() != "global":
self.facts['container'] = 'zone'
# Check if it's a branded zone (i.e. Solaris 8/9 zone)
@ -3008,7 +2948,7 @@ class SunOSVirtual(Virtual):
# If it's a zone check if we can detect if our global zone is itself virtualized.
# Relies on the "guest tools" (e.g. vmware tools) to be installed
if 'container' in self.facts and self.facts['container'] == 'zone':
rc, out, err = module.run_command("/usr/sbin/modinfo")
rc, out, err = self.module.run_command("/usr/sbin/modinfo")
for line in out.split('\n'):
if 'VMware' in line:
self.facts['virtualization_type'] = 'vmware'
@ -3020,7 +2960,7 @@ class SunOSVirtual(Virtual):
if os.path.exists("/usr/sbin/virtinfo"):
# The output of virtinfo is different whether we are on a machine with logical
# domains ('LDoms') on a T-series or domains ('Domains') on a M-series. Try LDoms first.
rc, out, err = module.run_command("/usr/sbin/virtinfo -p")
rc, out, err = self.module.run_command("/usr/sbin/virtinfo -p")
# The output contains multiple lines with different keys like this:
# DOMAINROLE|impl=LDoms|control=false|io=false|service=false|root=false
# The output may also be not formatted and the returncode is set to 0 regardless of the error condition:
@ -3071,28 +3011,24 @@ def get_file_lines(path):
def ansible_facts(module):
# Retrieve module parameters
gather_subset = [ 'all' ]
gather_subset = ('all',)
if 'gather_subset' in module.params:
gather_subset = module.params['gather_subset']
# Retrieve all facts elements
if 'all' in gather_subset:
gather_subset = [ 'min', 'hardware', 'network', 'virtual' ]
gather_subset = FACT_SUBSETS.keys()
else:
# Check subsets and forbid unallowed name
for subset in gather_subset:
if subset not in Facts.ALLOWED_FACT_SUBSET:
raise TypeError("Bad subset '%s' given to Ansible. gather_subset options allowed: %s" % (subset, ", ".join(Facts.ALLOWED_FACT_SUBSET)))
if subset not in FACT_SUBSETS.keys():
raise TypeError("Bad subset '%s' given to Ansible. gather_subset options allowed: all, %s" % (subset, ", ".join(FACT_SUBSETS.keys())))
facts = {}
facts.update(Facts().populate())
if 'hardware' in gather_subset:
facts.update(Hardware().populate())
if 'network' in gather_subset:
facts.update(Network(module).populate())
if 'virtual' in gather_subset:
facts.update(Virtual().populate())
facts['gather_subset'] = gather_subset
facts.update(Facts(module).populate())
for subset in gather_subset:
facts.update(FACT_SUBSETS[subset](module).populate())
return facts
# ===========================================
@ -3153,3 +3089,11 @@ def get_all_facts(module):
setup_result['_ansible_verbose_override'] = True
return setup_result
### Note: have to define this at the bottom as it references classes defined earlier in this file
# Allowed fact subset for gather_subset options and what classes they use
FACT_SUBSETS = dict(
hardware=Hardware,
network=Network,
virtual=Virtual,
)

View file

@ -64,7 +64,7 @@ class Play(Base, Taggable, Become):
# Connection
_gather_facts = FieldAttribute(isa='bool', default=None, always_post_validate=True)
_gather_subset = FieldAttribute(isa='string', default=None, always_post_validate=True)
_gather_subset = FieldAttribute(isa='list', default=None, always_post_validate=True)
_ignore_facter = FieldAttribute(isa='bool', default=None, always_post_validate=True)
_ignore_ohai = FieldAttribute(isa='bool', default=None, always_post_validate=True)
_hosts = FieldAttribute(isa='list', required=True, listof=string_types, always_post_validate=True)