<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[14892] CalDAVTester/trunk/odsetup.py</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/14892">14892</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2015-06-09 12:41:02 -0700 (Tue, 09 Jun 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Now uses OD.framework. Tests for unwanted OD binds. Use ConfigRoot from actual config rather than hard-coded path.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#CalDAVTestertrunkodsetuppy">CalDAVTester/trunk/odsetup.py</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalDAVTestertrunkodsetuppy"></a>
<div class="modfile"><h4>Modified: CalDAVTester/trunk/odsetup.py (14891 => 14892)</h4>
<pre class="diff"><span>
<span class="info">--- CalDAVTester/trunk/odsetup.py        2015-06-09 00:42:41 UTC (rev 14891)
+++ CalDAVTester/trunk/odsetup.py        2015-06-09 19:41:02 UTC (rev 14892)
</span><span class="lines">@@ -31,9 +31,35 @@
</span><span class="cx"> import uuid
</span><span class="cx"> import xml.parsers.expat
</span><span class="cx">
</span><ins>+"""
+OpenDirectory.framework
+"""
+
+import objc as _objc
+
+__bundle__ = _objc.initFrameworkWrapper(
+ "OpenDirectory",
+ frameworkIdentifier="com.apple.OpenDirectory",
+ frameworkPath=_objc.pathForFramework(
+ "/System/Library/Frameworks/OpenDirectory.framework"
+ ),
+ globals=globals()
+)
+
+# DS attributes we need
+kDSStdRecordTypeUsers = "dsRecTypeStandard:Users"
+kDSStdRecordTypeGroups = "dsRecTypeStandard:Groups"
+kDSStdRecordTypePlaces = "dsRecTypeStandard:Places"
+kDSStdRecordTypeResources = "dsRecTypeStandard:Resources"
+
+kDS1AttrGeneratedUID = "dsAttrTypeStandard:GeneratedUID"
+kDSNAttrRecordName = "dsAttrTypeStandard:RecordName"
+
+eDSExact = 0x2001
+
+
</ins><span class="cx"> sys_root = "/Applications/Server.app/Contents/ServerRoot"
</span><span class="cx"> os.environ["PATH"] = "%s/usr/bin:%s" % (sys_root, os.environ["PATH"])
</span><del>-conf_root = "/Library/Server/Calendar and Contacts/Config"
</del><span class="cx">
</span><span class="cx"> diradmin_user = "admin"
</span><span class="cx"> diradmin_pswd = ""
</span><span class="lines">@@ -120,9 +146,9 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> i18nattrs = {
</span><del>- "dsAttrTypeStandard:RealName": "まだ",
- "dsAttrTypeStandard:FirstName": "ま",
- "dsAttrTypeStandard:LastName": "だ",
</del><ins>+ "dsAttrTypeStandard:RealName": u"まだ",
+ "dsAttrTypeStandard:FirstName": u"ま",
+ "dsAttrTypeStandard:LastName": u"だ",
</ins><span class="cx"> "dsAttrTypeStandard:EMailAddress": "i18nuser@example.com",
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -232,15 +258,15 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> records = (
</span><del>- ("/Users", "testadmin", "testadmin", adminattrs, 1),
- ("/Users", "apprentice", "apprentice", apprenticeattrs, 1),
- ("/Users", "i18nuser", "i18nuser", i18nattrs, 1),
- ("/Users", "user%02d", "user%02d", userattrs, None),
- ("/Users", "public%02d", "public%02d", publicattrs, number_of_publics),
- ("/Places", "location%02d", "location%02d", locationattrs, number_of_locations),
- ("/Places", "delegatedroom", "delegatedroom", delegatedroomattrs, 1),
- ("/Resources", "resource%02d", "resource%02d", resourceattrs, number_of_resources),
- ("/Groups", "group%02d", "group%02d", groupattrs, number_of_groups),
</del><ins>+ (kDSStdRecordTypeUsers, "testadmin", "testadmin", adminattrs, 1),
+ (kDSStdRecordTypeUsers, "apprentice", "apprentice", apprenticeattrs, 1),
+ (kDSStdRecordTypeUsers, "i18nuser", "i18nuser", i18nattrs, 1),
+ (kDSStdRecordTypeUsers, "user%02d", "user%02d", userattrs, None),
+ (kDSStdRecordTypeUsers, "public%02d", "public%02d", publicattrs, number_of_publics),
+ (kDSStdRecordTypePlaces, "location%02d", "location%02d", locationattrs, number_of_locations),
+ (kDSStdRecordTypePlaces, "delegatedroom", "delegatedroom", delegatedroomattrs, 1),
+ (kDSStdRecordTypeResources, "resource%02d", "resource%02d", resourceattrs, number_of_resources),
+ (kDSStdRecordTypeGroups, "group%02d", "group%02d", groupattrs, number_of_groups),
</ins><span class="cx"> )
</span><span class="cx">
</span><span class="cx"> def usage():
</span><span class="lines">@@ -251,6 +277,7 @@
</span><span class="cx"> -u uid OpenDirectory Admin user id
</span><span class="cx"> -p pswd OpenDirectory Admin user password
</span><span class="cx"> -c users number of user accounts to create (default: 10)
</span><ins>+ -x disable OD node checks
</ins><span class="cx"> -v verbose logging
</span><span class="cx"> -V very verbose logging
</span><span class="cx"> """
</span><span class="lines">@@ -300,6 +327,83 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><ins>+class ODError(Exception):
+ pass
+
+
+
+class ODFamework(object):
+
+ def __init__(self, nodeName, user, pswd):
+ self.session = ODSession.defaultSession()
+ self.node, error = ODNode.nodeWithSession_name_error_(self.session, nodeName, None)
+ if error:
+ print(error)
+ raise ODError(error)
+
+ _ignore_result, error = self.node.setCredentialsWithRecordType_recordName_password_error_(
+ kDSStdRecordTypeUsers,
+ user,
+ pswd,
+ None
+ )
+ if error:
+ print("Unable to authenticate with directory %s: %s" % (nodeName, error))
+ raise ODError(error)
+
+ print("Successfully authenticated with directory %s" % (nodeName,))
+
+
+ def lookupRecordName(self, recordType, name):
+ query, error = ODQuery.queryWithNode_forRecordTypes_attribute_matchType_queryValues_returnAttributes_maximumResults_error_(
+ self.node,
+ recordType,
+ kDSNAttrRecordName,
+ eDSExact,
+ name,
+ [kDS1AttrGeneratedUID],
+ 0,
+ None)
+ if error:
+ raise ODError(error)
+ records, error = query.resultsAllowingPartial_error_(False, None)
+ if error:
+ raise ODError(error)
+
+ if len(records) < 1:
+ return None
+ if len(records) > 1:
+ raise ODError("Multiple records for '%s' were found" % (name,))
+
+ return records[0]
+
+
+ def createRecord(self, recordType, recordName, password, attrs):
+ record, error = self.node.createRecordWithRecordType_name_attributes_error_(
+ recordType,
+ recordName,
+ attrs,
+ None)
+ if error:
+ print(error)
+ raise ODError(error)
+ if recordType == kDSStdRecordTypeUsers:
+ _ignore_result, error = record.changePassword_toPassword_error_(None, password, None)
+ if error:
+ print(error)
+ raise ODError(error)
+ return record
+
+
+ def recordDetails(self, record):
+ details, error = record.recordDetailsForAttributes_error_(None, None)
+ if error:
+ print(error)
+ raise ODError(error)
+ return details
+
+
+
</ins><span class="cx"> def readConfig():
</span><span class="cx"> """
</span><span class="cx"> Read useful information from calendarserver_config
</span><span class="lines">@@ -308,6 +412,7 @@
</span><span class="cx"> args = [
</span><span class="cx"> configutility,
</span><span class="cx"> "ServerHostName",
</span><ins>+ "ConfigRoot",
</ins><span class="cx"> "DocumentRoot",
</span><span class="cx"> "HTTPPort",
</span><span class="cx"> "SSLPort",
</span><span class="lines">@@ -339,11 +444,12 @@
</span><span class="cx"> int(currentConfig["SSLPort"]),
</span><span class="cx"> authtype,
</span><span class="cx"> currentConfig["DocumentRoot"],
</span><ins>+ currentConfig["ConfigRoot"],
</ins><span class="cx"> )
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-def patchConfig(admin):
</del><ins>+def patchConfig(confroot, admin):
</ins><span class="cx"> """
</span><span class="cx"> Patch the caldavd-user.plist file to make sure:
</span><span class="cx"> * the proper admin principal is configured
</span><span class="lines">@@ -388,7 +494,7 @@
</span><span class="cx"> "lockRescheduleInterval": 1,
</span><span class="cx"> }
</span><span class="cx">
</span><del>- writePlist(plist, conf_root + "/caldavd-user.plist")
</del><ins>+ writePlist(plist, confroot + "/caldavd-user.plist")
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><span class="lines">@@ -447,9 +553,9 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> def loadLists(path, records):
</span><del>- if path == "/Places":
</del><ins>+ if path == kDSStdRecordTypePlaces:
</ins><span class="cx"> result = cmd(cmdutility, locationlistcmd)
</span><del>- elif path == "/Resources":
</del><ins>+ elif path == kDSStdRecordTypeResources:
</ins><span class="cx"> result = cmd(cmdutility, resourcelistcmd)
</span><span class="cx"> else:
</span><span class="cx"> raise ValueError()
</span><span class="lines">@@ -465,10 +571,10 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-def doToAccounts(protocol, f, users_only=False):
</del><ins>+def doToAccounts(odf, protocol, f, users_only=False):
</ins><span class="cx">
</span><span class="cx"> for record in records:
</span><del>- if protocol == "carddav" and record[0] in ("/Places", "/Resources"):
</del><ins>+ if protocol == "carddav" and record[0] in (kDSStdRecordTypePlaces, kDSStdRecordTypeResources):
</ins><span class="cx"> continue
</span><span class="cx"> if record[4] is None:
</span><span class="cx"> count = number_of_users
</span><span class="lines">@@ -484,13 +590,13 @@
</span><span class="cx"> value = value % (ctr,)
</span><span class="cx"> attrs[key] = value
</span><span class="cx"> ruser = (record[1] % (ctr,), record[2] % (ctr,), attrs, 1)
</span><del>- f(record[0], ruser)
</del><ins>+ f(odf, record[0], ruser)
</ins><span class="cx"> else:
</span><del>- f(record[0], record[1:])
</del><ins>+ f(odf, record[0], record[1:])
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-def doGroupMemberships():
</del><ins>+def doGroupMemberships(odf):
</ins><span class="cx">
</span><span class="cx"> memberships = (
</span><span class="cx"> ("group01", ("user01",), (),),
</span><span class="lines">@@ -503,60 +609,72 @@
</span><span class="cx"> )
</span><span class="cx">
</span><span class="cx"> for groupname, users, nestedgroups in memberships:
</span><ins>+ if verbose:
+ print "Group membership: {}".format(groupname)
</ins><span class="cx">
</span><del>- memberGUIDs = [guids[user] for user in users]
- nestedGUIDs = [guids[group] for group in nestedgroups]
</del><ins>+ # Get group record
+ group = odf.lookupRecordName(kDSStdRecordTypeGroups, groupname)
+ if group is not None:
+ for user in users:
+ member = odf.lookupRecordName(kDSStdRecordTypeUsers, user)
+ if member is not None:
+ _ignore_result, error = group.addMemberRecord_error_(member, None)
+ if error:
+ raise ODError(error)
+ for nested in nestedgroups:
+ member = odf.lookupRecordName(kDSStdRecordTypeGroups, nested)
+ if member is not None:
+ _ignore_result, error = group.addMemberRecord_error_(member, None)
+ if error:
+ raise ODError(error)
</ins><span class="cx">
</span><del>- cmd("dscl -u %s -P %s %s -append /Groups/%s \"dsAttrTypeStandard:GroupMembers\"%s" % (diradmin_user, diradmin_pswd, directory_node, groupname, "".join([" \"%s\"" % (guid,) for guid in memberGUIDs])), raiseOnFail=False)
- cmd("dscl -u %s -P %s %s -append /Groups/%s \"dsAttrTypeStandard:NestedGroups\"%s" % (diradmin_user, diradmin_pswd, directory_node, groupname, "".join([" \"%s\"" % (guid,) for guid in nestedGUIDs])), raiseOnFail=False)
</del><span class="cx">
</span><span class="cx">
</span><ins>+def createUser(odf, path, user):
</ins><span class="cx">
</span><del>-def createUser(path, user):
</del><ins>+ if verbose:
+ print "Create user: {}/{}".format(path, user[0])
</ins><span class="cx">
</span><del>- if path in ("/Users", "/Groups",):
- createUserViaDS(path, user)
</del><ins>+ if path in (kDSStdRecordTypeUsers, kDSStdRecordTypeGroups,):
+ createUserViaDS(odf, path, user)
</ins><span class="cx"> elif protocol == "caldav":
</span><span class="cx"> createUserViaGateway(path, user)
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-def createUserViaDS(path, user):
</del><ins>+def createUserViaDS(odf, path, user):
</ins><span class="cx"> # Do dscl command line operations to create a calendar user
</span><span class="cx">
</span><span class="cx"> # Only create if it does not exist
</span><del>- if cmd("dscl %s -list %s/%s" % (directory_node, path, user[0]), raiseOnFail=False)[1] != 0:
</del><ins>+ record = odf.lookupRecordName(path, user[0])
+
+ if record is None:
</ins><span class="cx"> # Create the user
</span><del>- cmd("dscl -u %s -P %s %s -create %s/%s" % (diradmin_user, diradmin_pswd, directory_node, path, user[0]))
</del><ins>+ if kDS1AttrGeneratedUID in user[2]:
+ user[2][kDS1AttrGeneratedUID] = str(uuid.uuid4()).upper()
</ins><span class="cx">
</span><del>- # Set the password (only for /Users)
- if path == "/Users":
- cmd("dscl -u %s -P %s %s -passwd %s/%s %s" % (diradmin_user, diradmin_pswd, directory_node, path, user[0], user[1]))
-
- # Other attributes
- for key, value in user[2].iteritems():
- if key == "dsAttrTypeStandard:GeneratedUID":
- value = str(uuid.uuid4()).upper()
- cmd("dscl -u %s -P %s %s -create %s/%s \"%s\" \"%s\"" % (diradmin_user, diradmin_pswd, directory_node, path, user[0], key, value))
</del><ins>+ user = (user[0], user[1], dict([(k, [v],) for k, v in user[2].items()]),)
+ record = odf.createRecord(path, user[0], user[1], user[2])
</ins><span class="cx"> else:
</span><del>- print "%s/%s already exists" % (path, user[0],)
</del><ins>+ if verbose:
+ print "%s/%s already exists" % (path, user[0],)
</ins><span class="cx">
</span><span class="cx"> # Now read the guid for this record
</span><span class="cx"> if user[0] in guids:
</span><del>- result = cmd("dscl %s -read %s/%s GeneratedUID" % (directory_node, path, user[0]))
- guid = result[0].split()[1]
- guids[user[0]] = guid
</del><ins>+ record = odf.lookupRecordName(path, user[0])
+ details = odf.recordDetails(record)
+ guids[user[0]] = details[kDS1AttrGeneratedUID][0]
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> def createUserViaGateway(path, user):
</span><span class="cx">
</span><span class="cx"> # Check for existing
</span><del>- if path == "/Places":
</del><ins>+ if path == kDSStdRecordTypePlaces:
</ins><span class="cx"> if user[0] in locations:
</span><span class="cx"> guids[user[0]] = locations[user[0]]
</span><span class="cx"> return
</span><del>- elif path == "/Resources":
</del><ins>+ elif path == kDSStdRecordTypeResources:
</ins><span class="cx"> if user[0] in resources:
</span><span class="cx"> guids[user[0]] = resources[user[0]]
</span><span class="cx"> return
</span><span class="lines">@@ -564,7 +682,7 @@
</span><span class="cx"> guid = str(uuid.uuid4()).upper()
</span><span class="cx"> if user[0] in guids:
</span><span class="cx"> guids[user[0]] = guid
</span><del>- if path == "/Places":
</del><ins>+ if path == kDSStdRecordTypePlaces:
</ins><span class="cx"> cmd(
</span><span class="cx"> cmdutility,
</span><span class="cx"> locationcreatecmd % {
</span><span class="lines">@@ -573,7 +691,7 @@
</span><span class="cx"> "recordname": user[0]
</span><span class="cx"> }
</span><span class="cx"> )
</span><del>- elif path == "/Resources":
</del><ins>+ elif path == kDSStdRecordTypeResources:
</ins><span class="cx"> cmd(
</span><span class="cx"> cmdutility,
</span><span class="cx"> resourcecreatecmd % {
</span><span class="lines">@@ -587,26 +705,32 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-def removeUser(path, user):
</del><ins>+def removeUser(odf, path, user):
</ins><span class="cx">
</span><del>- if path in ("/Users", "/Groups",):
- removeUserViaDS(path, user)
</del><ins>+ if verbose:
+ print "Remove user: {}/{}".format(path, user[0])
+
+ if path in (kDSStdRecordTypeUsers, kDSStdRecordTypeGroups,):
+ removeUserViaDS(odf, path, user)
</ins><span class="cx"> else:
</span><span class="cx"> removeUserViaGateway(path, user)
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-def removeUserViaDS(path, user):
</del><ins>+def removeUserViaDS(odf, path, user):
</ins><span class="cx"> # Do dscl command line operations to remove a calendar user
</span><span class="cx">
</span><del>- # Create the user
- cmd("dscl -u %s -P %s %s -delete %s/%s" % (diradmin_user, diradmin_pswd, directory_node, path, user[0]), raiseOnFail=False)
</del><ins>+ record = odf.lookupRecordName(path, user[0])
+ if record is not None:
+ _ignore_result, error = record.deleteRecordAndReturnError_(None)
+ if error:
+ raise ODError(error)
</ins><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><span class="cx"> def removeUserViaGateway(path, user):
</span><span class="cx">
</span><del>- if path == "/Places":
</del><ins>+ if path == kDSStdRecordTypePlaces:
</ins><span class="cx"> if user[0] not in locations:
</span><span class="cx"> return
</span><span class="cx"> guid = locations[user[0]]
</span><span class="lines">@@ -614,7 +738,7 @@
</span><span class="cx"> cmdutility,
</span><span class="cx"> locationremovecmd % {"guid": guid, }
</span><span class="cx"> )
</span><del>- elif path == "/Resources":
</del><ins>+ elif path == kDSStdRecordTypeResources:
</ins><span class="cx"> if user[0] not in resources:
</span><span class="cx"> return
</span><span class="cx"> guid = resources[user[0]]
</span><span class="lines">@@ -627,14 +751,14 @@
</span><span class="cx">
</span><span class="cx">
</span><span class="cx">
</span><del>-def manageRecords(path, user):
</del><ins>+def manageRecords(odf, path, user):
</ins><span class="cx"> """
</span><span class="cx"> Set proxies and auto-schedule for locations and resources
</span><span class="cx"> """
</span><span class="cx">
</span><span class="cx"> # Do caldav_utility setup
</span><del>- if path in ("/Places", "/Resources",):
- if path in ("/Places",):
</del><ins>+ if path in (kDSStdRecordTypePlaces, kDSStdRecordTypeResources,):
+ if path in (kDSStdRecordTypePlaces,):
</ins><span class="cx"> if user[0] == "delegatedroom":
</span><span class="cx"> cmd("%s --add-write-proxy groups:group05 --add-read-proxy groups:group07 --set-auto-schedule-mode=none locations:%s" % (
</span><span class="cx"> utility,
</span><span class="lines">@@ -686,8 +810,9 @@
</span><span class="cx">
</span><span class="cx"> protocol = "caldav"
</span><span class="cx"> serverinfo_default = details[protocol]["serverinfo"]
</span><ins>+ node_check = True
</ins><span class="cx"> try:
</span><del>- options, args = getopt.getopt(sys.argv[1:], "hn:p:u:f:c:vV")
</del><ins>+ options, args = getopt.getopt(sys.argv[1:], "hn:p:u:f:c:vVx")
</ins><span class="cx">
</span><span class="cx"> for option, value in options:
</span><span class="cx"> if option == "-h":
</span><span class="lines">@@ -706,6 +831,8 @@
</span><span class="cx"> elif option == "-V":
</span><span class="cx"> verbose = True
</span><span class="cx"> veryverbose = True
</span><ins>+ elif option == "-x":
+ node_check = False
</ins><span class="cx"> else:
</span><span class="cx"> print "Unrecognized option: %s" % (option,)
</span><span class="cx"> usage()
</span><span class="lines">@@ -728,23 +855,26 @@
</span><span class="cx"> usage()
</span><span class="cx"> raise ValueError
</span><span class="cx">
</span><del>- checkDataSource(directory_node)
</del><ins>+ odf = ODFamework(directory_node, diradmin_user, diradmin_pswd)
</ins><span class="cx">
</span><ins>+ if node_check:
+ checkDataSource(directory_node)
+
</ins><span class="cx"> if args[0] == "create":
</span><span class="cx"> # Read the caldavd.plist file and extract some information we will need.
</span><del>- hostname, port, sslport, authtype, docroot = readConfig()
</del><ins>+ hostname, port, sslport, authtype, docroot, confroot = readConfig()
</ins><span class="cx">
</span><span class="cx"> # Now generate the OD accounts (caching guids as we go).
</span><span class="cx"> if protocol == "caldav":
</span><del>- loadLists("/Places", locations)
- loadLists("/Resources", resources)
</del><ins>+ loadLists(kDSStdRecordTypePlaces, locations)
+ loadLists(kDSStdRecordTypeResources, resources)
</ins><span class="cx">
</span><del>- doToAccounts(protocol, createUser)
- doGroupMemberships()
- doToAccounts(protocol, manageRecords)
</del><ins>+ doToAccounts(odf, protocol, createUser)
+ doGroupMemberships(odf)
+ doToAccounts(odf, protocol, manageRecords)
</ins><span class="cx">
</span><span class="cx"> # Patch the caldavd.plist file with the testadmin user's guid-based principal-URL
</span><del>- patchConfig("/principals/__uids__/%s/" % (guids["testadmin"],))
</del><ins>+ patchConfig(confroot, "/principals/__uids__/%s/" % (guids["testadmin"],))
</ins><span class="cx">
</span><span class="cx"> # Create an appropriate serverinfo.xml file from the template
</span><span class="cx"> buildServerinfo(serverinfo_default, hostname, port, sslport, authtype, docroot)
</span><span class="lines">@@ -752,23 +882,23 @@
</span><span class="cx">
</span><span class="cx"> elif args[0] == "create-users":
</span><span class="cx"> # Read the caldavd.plist file and extract some information we will need.
</span><del>- hostname, port, sslport, authtype, docroot = readConfig()
</del><ins>+ hostname, port, sslport, authtype, docroot, confroot = readConfig()
</ins><span class="cx">
</span><span class="cx"> # Now generate the OD accounts (caching guids as we go).
</span><span class="cx"> if protocol == "caldav":
</span><del>- loadLists("/Places", locations)
- loadLists("/Resources", resources)
</del><ins>+ loadLists(kDSStdRecordTypePlaces, locations)
+ loadLists(kDSStdRecordTypeResources, resources)
</ins><span class="cx">
</span><del>- doToAccounts(protocol, createUser, users_only=True)
</del><ins>+ doToAccounts(odf, protocol, createUser, users_only=True)
</ins><span class="cx">
</span><span class="cx"> # Create an appropriate serverinfo.xml file from the template
</span><span class="cx"> buildServerinfo(serverinfo_default, hostname, port, sslport, authtype, docroot)
</span><span class="cx">
</span><span class="cx"> elif args[0] == "remove":
</span><span class="cx"> if protocol == "caldav":
</span><del>- loadLists("/Places", locations)
- loadLists("/Resources", resources)
- doToAccounts(protocol, removeUser)
</del><ins>+ loadLists(kDSStdRecordTypePlaces, locations)
+ loadLists(kDSStdRecordTypeResources, resources)
+ doToAccounts(odf, protocol, removeUser)
</ins><span class="cx">
</span><span class="cx"> except Exception, e:
</span><span class="cx"> traceback.print_exc()
</span></span></pre>
</div>
</div>
</body>
</html>