Skip to content

Instantly share code, notes, and snippets.

@JDHatman
Created May 2, 2014 19:36
Show Gist options
  • Save JDHatman/a40645d12c600747539f to your computer and use it in GitHub Desktop.
Save JDHatman/a40645d12c600747539f to your computer and use it in GitHub Desktop.
sal-submit
#!/usr/bin/python
#
# postflight
# Submits inventory to an instance of Sal
#
# Last Revised - 2014-04-09
import sys
sys.path.append('/usr/local/sal')
import urllib
import urllib2
# try to import from the default place Munki installs it
try:
from munkilib import FoundationPlist
except:
sys.path.append('/usr/local/munki')
from munkilib import FoundationPlist
from Foundation import *
import subprocess
import base64
import yaml
import bz2
import os
import sys
BUNDLE_ID = 'com.grahamgilbert.sal'
def get_disk_size(path='/'):
"""Returns total disk size in KBytes.
Args:
path: str, optional, default '/'
Returns:
int, KBytes in total disk space
"""
if path is None:
path = '/'
try:
st = os.statvfs(path)
except OSError, e:
display_error(
'Error getting disk space in %s: %s', path, str(e))
return 0
total = (st.f_blocks * st.f_frsize) / 1024
return int(total)
def getconsoleuser():
"""Return console user"""
from SystemConfiguration import SCDynamicStoreCopyConsoleUser
cfuser = SCDynamicStoreCopyConsoleUser( None, None, None )
return cfuser[0]
def set_pref(pref_name, pref_value):
"""Sets a preference, writing it to
/Library/Preferences/com.grahamgilbert.sal.plist.
This should normally be used only for 'bookkeeping' values;
values that control the behavior of munki may be overridden
elsewhere (by MCX, for example)"""
try:
CFPreferencesSetValue(
pref_name, pref_value, BUNDLE_ID,
kCFPreferencesAnyUser, kCFPreferencesCurrentHost)
CFPreferencesAppSynchronize(BUNDLE_ID)
except Exception:
pass
def pref(pref_name):
"""Return a preference. Since this uses CFPreferencesCopyAppValue,
Preferences can be defined several places. Precedence is:
- MCX
- /var/root/Library/Preferences/com.grahamgilbert.sal.plist
- /Library/Preferences/com.grahamgilbert.sal.plist
- default_prefs defined here.
"""
default_prefs = {
'ServerURL': 'http://sal',
}
pref_value = CFPreferencesCopyAppValue(pref_name, BUNDLE_ID)
if pref_value == None:
pref_value = default_prefs.get(pref_name)
# we're using a default value. We'll write it out to
# /Library/Preferences/<BUNDLE_ID>.plist for admin
# discoverability
set_pref(pref_name, pref_value)
if isinstance(pref_value, NSDate):
# convert NSDate/CFDates to strings
pref_value = str(pref_value)
return pref_value
# read in the serverURL
ServerURL = pref('ServerURL');
checkinurl = ServerURL+'/checkin'
# read in the BU Key
bu_key = pref('key')
# read in Munki Report
report = FoundationPlist.readPlist('/Library/Managed Installs/ManagedInstallReport.plist')
# generate system profiler report
command = ['system_profiler', '-xml', 'SPNetworkDataType', 'SPHardwareDataType']
task = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = task.communicate()
system_profile = FoundationPlist.readPlistFromString(stdout)
try:
f = open('/var/lib/puppet/state/last_run_summary.yaml', 'r')
puppetreport = yaml.load(f.read())
report['Puppet'] = puppetreport
except:
pass
# Merge the system profiler report into the Munki report
report['MachineInfo']['SystemProfile'] = system_profile
# Set the FACTERLIB environment variable if it's not already what we want it to be.
desiredfacter = '/usr/local/sal/facter:'
facterlib = os.environ.get('FACTERLIB')
facterflag = False
if facterlib:
if desiredfacter not in facterlib:
# set the flag to true, we need to put it back
facterflag = True
os.environ['FACTERLIB'] = desiredfacter
# if Puppet is installed, get it's verion
try:
command = ['/usr/bin/puppet', '--version']
task = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = task.communicate()
if stdout:
report['Puppet_Version'] = stdout
except:
print stderr
# if Facter is installed, perform a run
try:
command = ['/usr/bin/facter', '--puppet', '--yaml']
task = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = task.communicate()
if stdout:
facter = yaml.load(stdout)
report['Facter'] = facter
except:
print stderr
# Get the serial number
try:
serial = report['MachineInfo']['serial_number']
except:
print 'Unable to get MachineInfo from ManagedInstallReport.plist. This is usually due to running Munki in Apple Software only mode.'
sys.exit(0)
# Get Machine Name
command = ['/usr/sbin/scutil', '--get', 'ComputerName']
task = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = task.communicate()
name = stdout
data = {}
# Set the OS family
report['os_family'] = 'Darwin'
# Compress the report
plist = FoundationPlist.writePlistToString(report)
zipped = bz2.compress(plist)
data['base64bz2report'] = base64.b64encode(zipped)
data['serial'] = serial
data['key'] = bu_key
data['name'] = name
data['disk_size'] = get_disk_size('/')
data = urllib.urlencode(data)
req = urllib2.Request(checkinurl, data)
response = urllib2.urlopen(req)
response = response.read()
# cleanup
if facterflag:
os.environ['FACTERLIB'] = facterlib
print response
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment