Merge pull request #3228 from skvidal/facts.d

first cut and docs for facts.d mechanism for setup module
This commit is contained in:
Michael DeHaan 2013-06-16 19:46:02 -07:00
commit c3544de1df

View file

@ -30,6 +30,9 @@ import struct
import datetime
import getpass
import subprocess
import ConfigParser
import StringIO
DOCUMENTATION = '''
---
@ -42,6 +45,15 @@ options:
- if supplied, only return facts that match this shell-style (fnmatch) wildcard.
required: false
default: '*'
fact_path:
version_added: "1.3"
description:
- path used for local ansible facts (*.fact) - files in this dir
will be run (if executable) and their results be added to ansible_local facts
if a file is not executable it is read.
File/results format can be json or ini-format
required: false
default: '/etc/ansible/facts.d'
description:
- This module is automatically called by playbooks to gather useful
variables about remote hosts that can be used in playbooks. It can also be
@ -131,6 +143,7 @@ class Facts(object):
self.get_lsb_facts()
self.get_date_time_facts()
self.get_user_facts()
self.get_local_facts()
def populate(self):
return self.facts
@ -169,6 +182,51 @@ class Facts(object):
self.facts['architecture'] = data[0]
def get_local_facts(self):
fact_path = module.params.get('fact_path', None)
if not fact_path or not os.path.exists(fact_path):
return
local = {}
for fn in sorted(glob.glob(fact_path + '/*.fact')):
# where it will sit under local facts
fact_base = os.path.basename(fn).replace('.fact','')
if os.access(fn, os.X_OK):
# run it
# 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)
else:
out = open(fn).read()
# load raw json
fact = 'loading %s' % fact_base
try:
fact = json.loads(out)
except ValueError, e:
# load raw ini
cp = ConfigParser.ConfigParser()
try:
cp.readfp(StringIO.StringIO(out))
except ConfigParser.Error, e:
fact="error loading fact - please check content"
else:
fact = {}
#print cp.sections()
for sect in cp.sections():
if sect not in fact:
fact[sect] = {}
for opt in cp.options(sect):
val = cp.get(sect, opt)
fact[sect][opt]=val
local[fact_base] = fact
if not local:
return
self.facts['local'] = local
# platform.dist() is deprecated in 2.6
# in 2.6 and newer, you should use platform.linux_distribution()
def get_distribution_facts(self):
@ -2044,6 +2102,7 @@ def main():
module = AnsibleModule(
argument_spec = dict(
filter=dict(default="*", required=False),
fact_path=dict(default='/etc/ansible/facts.d', required=False),
),
supports_check_mode = True,
)