我们使用Python脚本与Deploy Studio服务器通信,以使用Deploy Studio的Web访问URL自动更新用户和计算机信息。由于最近的更改,他们现在以二进制plist格式存储计算机的Plists,而不是XML。
以下是目前适用于旧版DS的内容(来源:http://macops.ca/interfacing-with-deploystudio-using-http/):
#!/usr/bin/python
import urllib2
import plistlib
from random import randrange
host = 'https://my.ds.repo:60443'
adminuser = 'testdsuser'
adminpass = '12345'
def setupAuth():
"""Install an HTTP Basic Authorization header globally so it's used for
every request."""
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(realm='DeployStudioServer',
uri=host,
user=adminuser,
passwd=adminpass)
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
def getHostData(machine_id):
"""Return the full plist for a computer entry"""
machine_data = urllib2.urlopen(host + '/computers/get/entry?id=%s' % machine_id)
plist = plistlib.readPlistFromString(machine_data.read())
# if id isn't found, result will be an empty plist
return plist
def updateHostProperties(machine_id, properties, key_mac_addr=False, create_new=False):
"""Update the computer at machine_id with properties, a dict of properties and
values we want to set with new values. Return the full addinfourl object or None
if we found no computer to update and we aren't creating a new one. Set create_new
to True in order to enable creating new entries."""
found_comp = getHostData(machine_id)
# If we found no computer and we don't want a new record created
if not found_comp and not create_new:
return None
new_data = {}
if found_comp:
# Computer data comes back as plist nested like: {'SERIALNO': {'cn': 'my-name'}}
# DeployStudioServer expects a /set/entry POST like: {'cn': 'my-new-name'}
# so we copy the keys up a level
update = dict((k, v) for (k, v) in found_comp[machine_id].items())
new_data = update.copy()
else:
# No computer exists for this ID, we need to set up two required keys:
# 'dstudio-host-primary-key' and one of 'dstudio-host-serial-number'
# or 'dstudio-mac-addr' is required, otherwise request is ignored
# - IOW: you can't only rely on status codes
# - primary key is a server-level config, but we seem to need this per-host
if key_mac_addr:
new_data['dstudio-host-primary-key'] = 'dstudio-mac-addr'
else:
new_data['dstudio-host-primary-key'] = 'dstudio-host-serial-number'
new_data[new_data['dstudio-host-primary-key']] = machine_id
for (k, v) in properties.items():
new_data[k] = v
plist_to_post = plistlib.writePlistToString(new_data)
result = urllib2.urlopen(host + '/computers/set/entry?id=' + machine_id,
plist_to_post)
return result
def main():
setupAuth()
# Update HOWSANNIE with a new computer name (assuming this entry already exists)
random_name = 'random-id-' + str(randrange(100))
result = updateHostProperties('HOWSANNIE', {'cn': random_name,
'dstudio-hostname': random_name})
# Update DOUGLASFIRS with a new computername and custom properties, or create
# it if it doesn't already exist
random_name = 'random-id-' + str(randrange(100))
updateHostProperties('DOUGLASFIRS',
{'cn': random_name,
'dstudio-hostname': random_name,
'dstudio-custom-properties': [{
'dstudio-custom-property-key': 'ASSET_TAG',
'dstudio-custom-property-label': 'My Great Asset Tag',
'dstudio-custom-property-value': 'BL4CKL0DG3'}]
},
create_new=True)
if __name__ == "__main__":
main()
我们将此与本土Web界面结合使用,技术人员可在重新映像计算机时输入信息并自动更新DS数据库中的信息。
我尝试使用biplist这样的库无济于事。我更喜欢不必在服务器上本地存储文件,然后使用bash命令plutil进行转换。无论如何我可以操纵信息存储到的变量吗?在这种情况下,它将是' machine_data'。
我已成功使用带有-o标志的bash命令curl来指示将文件保存为有效的.plist文件,但如前所述,我想这样做而不保存本地文件,如果可能的。
部署可用的Studio Web服务:。
答案 0 :(得分:1)
将所有@ martijn-pieters评论整合到一个答案中:
pip install biplist
import urllib2
import io
import biplist
sock = urllib2.urlopen('https://cfpropertylist.googlecode.com/svn/trunk/examples/sample.binary.plist' )
buf = io.BytesIO(sock.read())
xml = biplist.readPlist(buf)
print xml
输出:
{'Pets Names':[],'Name':'John Doe','Picture':'< B \ x81 \ xa5 \ x81 \ xa5 \ x99 \ x81B<','出生年份': 1965年,“毕业日期”:datetime.datetime(2004,6,22,19,23,43),“出生之城”:“斯普林菲尔德”,“儿童名字”:['John','Kyra']}