4 title: Configuring collection's managed properties
8 Copyright (C) The Arvados Authors. All rights reserved.
10 SPDX-License-Identifier: CC-BY-SA-3.0
13 Collection's managed properties allow a cluster administrator to enable some special behaviors regarding properties at creation & update times.
14 This page describes how to enable and configure these behaviors on the API server.
16 h3. API Server configuration
18 The @Collections.ManagedProperties@ setting from the @config.yml@ file is used for enabling any of the following behaviors:
20 h4. Pre-assigned property key & value
22 For every newly created collection, assign a predefined key/value pair if it isn't already passed at creation time:
30 h4. Original owner UUID
32 This behavior will assign to a property key the UUID of the user who owns the collection's contaning project.
37 responsible_person_uuid: {function: original_owner}
40 h4. Protected properties
42 If there's a need to prevent a non-admin user from modifying a specific property, even by its owner, the @protected@ attribute can be set to @true@, like so:
47 responsible_person_uuid: {function: original_owner, protected: true}
50 This property can be applied to any of the defined managed properties. If missing, it's assumed as being @false@ by default.
52 h3. Supporting example scripts
54 When enabling this feature, there may be pre-existing collections that won't have the managed properties just configured. The following script examples may be helpful to sync these older collections.
56 For the following examples we assume that the @responsible_person_uuid@ property is set as @{function: original_owner, protected: true}@.
58 h4. List uuid/names of collections without @responsible_person_uuid@ property
60 {% codeblock as python %}
67 filters = [['properties.responsible_person_uuid', 'exists', False]]
69 req = api.collections().list(filters=filters, select=['uuid', 'name'], limit=page).execute()
72 cols += [c for c in req['items']]
73 if req['items_available'] < offset+page:
76 req = api.collections().list(filters=filters, select=['uuid', 'name'], limit=page, offset=offset).execute()
78 print("Found {} collections:".format(len(cols)))
80 print('{}, "{}"'.format(c['uuid'], c['name']))
83 h4. Update the @responsible_person_uuid@ property from nil to X in the project hierarchy rooted at P
85 {% codeblock as python %}
88 def get_subproject_uuids(api, root_uuid):
92 r = api.groups().list(
93 filters=[['owner_uuid', '=', '{}'.format(root_uuid)]],
99 uuids += ([g['uuid']] + get_subproject_uuids(api, g['uuid']))
100 if r['items_available'] < offset+page:
103 r = api.groups().list(
104 filters=[['owner_uuid', '=', '{}'.format(root_uuid)]],
110 def get_cols(api, filters):
114 r = api.collections().list(filters=filters, select=['uuid', 'properties'], limit=page).execute()
116 uuids += [c for c in r['items']]
117 if r['items_available'] < offset+page:
120 r = api.collections().list(filters=filters, select=['uuid', 'properties'], limit=page).execute()
123 root_uuid = 'zzzzz-j7d0g-ppppppppppppppp'
124 responsible_uuid = 'zzzzz-tpzed-xxxxxxxxxxxxxxx'
127 for p_uuid in [root_uuid] + get_subproject_uuids(api, root_uuid):
128 f = [['properties.responsible_person_uuid', 'exists', False],
129 ['owner_uuid', '=', p_uuid]]
130 cols = get_cols(api, f)
131 print("Found {} collections owned by {}".format(len(cols), p_uuid))
133 print(" - Updating collection {}".format(c["uuid"]))
134 props = c['properties']
135 props['responsible_person_uuid'] = responsible_uuid
136 api.collections().update(uuid=c['uuid'], body={'properties': props}).execute()
139 h4. Update the @responsible_person_uuid@ property from X to Y
141 The following code should run with admin privileges, assuming that the managed property is @protected@.
143 {% codeblock as python %}
146 old_uuid = "zzzzz-tpzed-xxxxxxxxxxxxxxx"
147 new_uuid = "zzzzz-tpzed-yyyyyyyyyyyyyyy"
153 filters = [['properties.responsible_person_uuid', '=', '{}'.format(old_uuid)]]
155 req = api.collections().list(filters=filters, select=['uuid', 'properties'], limit=page).execute()
158 cols += [c for c in req['items']]
159 if req['items_available'] < offset+page:
162 req = api.collections().list(filters=filters, select=['uuid', 'properties'], limit=page, offset=offset).execute()
164 print("Found {} collections".format(len(cols)))
166 print("Updating collection {}".format(c["uuid"]))
167 props = c['properties']
168 props['responsible_person_uuid'] = new_uuid
169 api.collections().update(uuid=c['uuid'], body={'properties': props}).execute()