mirror of
https://github.com/munki/munki.git
synced 2026-05-07 21:09:38 -05:00
Removed changes to predicateEvaluatesAsTrue. Conditional scripts must now write output to ConditionalItems.plist which is then parsed to the CONDITIONS dict for inclusion into the INFO_OBJECT dict
This commit is contained in:
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
plist_loc="/Library/Managed Installs/ConditionalItems"
|
||||
|
||||
IFS=$'\n'
|
||||
for hardware_port in `networksetup -listallhardwareports | awk -F ": " '/Hardware Port/{print $2}'`; do
|
||||
hardware_ports+=( $hardware_port )
|
||||
done
|
||||
|
||||
defaults write "$plist_loc" "hardware_ports" -array "${hardware_ports[@]}"
|
||||
plutil -convert xml1 "$plist_loc".plist
|
||||
|
||||
exit 0
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/python
|
||||
'''This is a basic example of a conditional script which outputs 2 key/value pairs:
|
||||
Examples:
|
||||
if_name,en0
|
||||
ip_address,192.168.1.128
|
||||
if_name: en0
|
||||
ip_address: 192.168.1.128
|
||||
|
||||
NOTE: Information gathered is ONLY for the primary interface'''
|
||||
|
||||
@@ -10,8 +10,10 @@ from SystemConfiguration import * # from pyObjC
|
||||
import socket
|
||||
import collections
|
||||
import os
|
||||
import plistlib
|
||||
|
||||
NETWORK_INFO = {}
|
||||
PREFSPATH = "/Library/Managed Installs/ConditionalItems.plist"
|
||||
|
||||
def getIPAddress(service_uuid):
|
||||
# print service_uuid
|
||||
@@ -46,8 +48,19 @@ def getNetworkInfo():
|
||||
NETWORK_INFO['service_uuid'] = serviceDict[u'PrimaryService']
|
||||
NETWORK_INFO['router'] = serviceDict[u'Router']
|
||||
NETWORK_INFO['ip_address'] = getIPAddress(serviceDict[u'PrimaryService'])
|
||||
print "if_name,%s" % ifname
|
||||
print "ip_address,%s" % NETWORK_INFO['ip_address']
|
||||
|
||||
new_dict = dict(
|
||||
if_name = ifname,
|
||||
ip_address = NETWORK_INFO['ip_address'],
|
||||
)
|
||||
|
||||
if os.path.exists(PREFSPATH):
|
||||
existing_dict = plistlib.readPlist(PREFSPATH)
|
||||
pl_dict = dict(existing_dict.items() + new_dict.items())
|
||||
else:
|
||||
pl_dict = new_dict
|
||||
|
||||
plistlib.writePlist(pl_dict, PREFSPATH)
|
||||
|
||||
|
||||
getNetworkInfo()
|
||||
|
||||
@@ -1945,52 +1945,37 @@ CONDITIONS = {}
|
||||
def getConditions():
|
||||
"""Fetches key/value pairs from condition scripts
|
||||
which can be placed into /usr/local/munki/conditions"""
|
||||
global CONDITIONS
|
||||
if not CONDITIONS:
|
||||
# define path to conditions directory which would contain admin created scripts
|
||||
scriptdir = os.path.realpath(os.path.dirname(sys.argv[0]))
|
||||
conditionsdir = os.path.join(scriptdir, "conditions")
|
||||
if os.path.exists(conditionsdir):
|
||||
conditionalscriptdir = os.path.join(scriptdir, "conditions")
|
||||
# define path to ConditionalItems.plist
|
||||
conditionalitemspath = os.path.join(pref('ManagedInstallDir'), 'ConditionalItems.plist')
|
||||
try:
|
||||
# delete CondtionalItems.plist so that we're starting fresh
|
||||
os.unlink(conditionalitemspath)
|
||||
except (OSError, IOError):
|
||||
pass
|
||||
if os.path.exists(conditionalscriptdir):
|
||||
from munkilib import utils
|
||||
for condition_script in listdir(conditionsdir):
|
||||
# grab path to each condition script
|
||||
condition_script_path = os.path.join(conditionsdir, condition_script)
|
||||
for conditionalscript in listdir(conditionalscriptdir):
|
||||
conditiondalscriptpath = os.path.join(conditionalscriptdir, conditionalscript)
|
||||
try:
|
||||
# attempt to execute condition script
|
||||
result, stdout, stderr = utils.runExternalScript(condition_script_path)
|
||||
# condition scripts may contain multi-line output,
|
||||
# each representing a key/value pair
|
||||
condition_stdout = stdout.splitlines()
|
||||
for condition in condition_stdout:
|
||||
# format and prepare each line for inclusion into the CONDITIONS dict
|
||||
condition = str(condition)
|
||||
key_value_pair = filter(len,[x.strip() for x in condition.split(',')])
|
||||
key_value_length = len(key_value_pair)
|
||||
if key_value_length == 2:
|
||||
# traditional key/value pairing
|
||||
condition_key = key_value_pair[0]
|
||||
condition_value = key_value_pair[1]
|
||||
elif key_value_length > 2:
|
||||
# 'complex' key/value pairing - value is a list of multiple values
|
||||
# keys with multiple values are cast as an NSArray.
|
||||
# This allows for a slightly different predicate evaluation
|
||||
condition_key = key_value_pair[0]
|
||||
condition_value = key_value_pair[1:]
|
||||
condition_value = NSArray.arrayWithArray_(condition_value)
|
||||
else:
|
||||
# key/value pair is invalid
|
||||
pass
|
||||
try:
|
||||
# Build dict of condition key/value pairs
|
||||
CONDITIONS[condition_key] = condition_value
|
||||
except:
|
||||
display_warning('No valid key/value pairs: %s', condition_script)
|
||||
result, stdout, stderr = utils.runExternalScript(conditiondalscriptpath)
|
||||
except utils.ScriptNotFoundError:
|
||||
pass # script is not required, so pass
|
||||
except utils.RunExternalScriptError, e:
|
||||
print >> sys.stderr, str(e)
|
||||
else:
|
||||
# /usr/local/munki/conditions does not exist
|
||||
pass
|
||||
# /usr/local/munki/conditions does not exist
|
||||
pass
|
||||
if os.path.exists(conditionalitemspath):
|
||||
# import conditions into CONDITIONS dict
|
||||
CONDITIONS = FoundationPlist.readPlist(conditionalitemspath)
|
||||
else:
|
||||
CONDITIONS = {}
|
||||
return CONDITIONS
|
||||
|
||||
|
||||
|
||||
@@ -1637,21 +1637,6 @@ def makePredicateInfoObject():
|
||||
def predicateEvaluatesAsTrue(predicate_string):
|
||||
'''Evaluates predicate against our info object'''
|
||||
munkicommon.display_debug1('Evaluating predicate: %s' % predicate_string)
|
||||
|
||||
# Parse condition item key from the predicate string
|
||||
condition_key = predicate_string.split()[0]
|
||||
if not condition_key in INFO_OBJECT:
|
||||
# Stop processing a predicate if it's conditional item key has not been defined
|
||||
munkicommon.display_warning('Condition "%s" is undefined', condition_key)
|
||||
return False
|
||||
|
||||
valueIsArray = False
|
||||
if "array" in str(type(INFO_OBJECT[condition_key])).lower():
|
||||
# Test if the key's value is an array and prepare a new predicate string
|
||||
predicate_string_orig = predicate_string
|
||||
# Manipulate predicate_string in prep for different evaluation
|
||||
predicate_string = predicate_string.replace(condition_key,'SELF')
|
||||
valueIsArray = True
|
||||
try:
|
||||
p = NSPredicate.predicateWithFormat_(predicate_string)
|
||||
except Exception, e:
|
||||
@@ -1659,18 +1644,7 @@ def predicateEvaluatesAsTrue(predicate_string):
|
||||
# can't parse predicate, so return False
|
||||
return False
|
||||
|
||||
if not valueIsArray:
|
||||
# Traditional key/value pair evaluation
|
||||
result = p.evaluateWithObject_(INFO_OBJECT)
|
||||
else:
|
||||
# Complex key/value pair evaluation
|
||||
if INFO_OBJECT[condition_key].filteredArrayUsingPredicate_(p):
|
||||
result = True
|
||||
else:
|
||||
result = False
|
||||
# Set predicate string back to it's original form for easier comprehension
|
||||
predicate_string = predicate_string_orig
|
||||
|
||||
result = p.evaluateWithObject_(INFO_OBJECT)
|
||||
munkicommon.display_debug1(
|
||||
'Predicate %s is %s' % (predicate_string, result))
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user