--- layout: default navsection: admin title: Configuring collection's managed properties ... {% comment %} Copyright (C) The Arvados Authors. All rights reserved. SPDX-License-Identifier: CC-BY-SA-3.0 {% endcomment %} Collection's managed properties allow a cluster administrator to enable some special behaviors regarding properties at creation & update times. This page describes how to enable and configure these behaviors on the API server. h3. API Server configuration The @Collections.ManagedProperties@ setting from the @config.yml@ file is used for enabling any of the following behaviors: h4. Pre-assigned property key & value For every newly created collection, assign a predefined key/value pair if it isn't already passed at creation time:
Collections:
  ManagedProperties:
    foo: {value: bar}
h4. Original owner UUID This behavior will assign to a property key the UUID of the user who owns the collection's contaning project.
Collections:
  ManagedProperties:
    responsible_person_uuid: {function: original_owner}
h4. Protected properties 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:
Collections:
  ManagedProperties:
    responsible_person_uuid: {function: original_owner, protected: true}
This property can be applied to any of the defined managed properties. If missing, it's assumed as being @false@ by default. h3. Supporting example scripts 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. For the following examples we assume that the @responsible_person_uuid@ property is set as @{function: original_owner, protected: true}@. h4. List uuid/names of collections without @responsible_person_uuid@ property {% codeblock as python %} import arvados page = 100 offset = 0 cols = [] filters = [['properties.responsible_person_uuid', 'exists', False]] api = arvados.api() req = api.collections().list(filters=filters, select=['uuid', 'name'], limit=page).execute() while True: cols += [c for c in req['items']] if req['items_available'] < offset+page: break offset += page req = api.collections().list(filters=filters, select=['uuid', 'name'], limit=page, offset=offset).execute() print("Found {} collections:".format(len(cols))) for c in cols: print('{}, "{}"'.format(c['uuid'], c['name'])) {% endcodeblock %} h4. Update the @responsible_person_uuid@ property from nil to X in the project hierarchy rooted at P {% codeblock as python %} import arvados def get_subproject_uuids(api, root_uuid): page = 100 offset = 0 uuids = [] r = api.groups().list( filters=[['owner_uuid', '=', '{}'.format(root_uuid)]], select=['uuid'], limit=page ).execute() while True: for g in r['items']: uuids += ([g['uuid']] + get_subproject_uuids(api, g['uuid'])) if r['items_available'] < offset+page: break offset += page r = api.groups().list( filters=[['owner_uuid', '=', '{}'.format(root_uuid)]], select=['uuid'], limit=page ).execute() return uuids def get_cols(api, filters): page = 100 offset = 0 uuids = [] r = api.collections().list(filters=filters, select=['uuid', 'properties'], limit=page).execute() while True: uuids += [c for c in r['items']] if r['items_available'] < offset+page: break offset += page r = api.collections().list(filters=filters, select=['uuid', 'properties'], limit=page).execute() return uuids root_uuid = 'zzzzz-j7d0g-ppppppppppppppp' responsible_uuid = 'zzzzz-tpzed-xxxxxxxxxxxxxxx' api = arvados.api() for p_uuid in [root_uuid] + get_subproject_uuids(api, root_uuid): f = [['properties.responsible_person_uuid', 'exists', False], ['owner_uuid', '=', p_uuid]] cols = get_cols(api, f) print("Found {} collections owned by {}".format(len(cols), p_uuid)) for c in cols: print(" - Updating collection {}".format(c["uuid"])) props = c['properties'] props['responsible_person_uuid'] = responsible_uuid api.collections().update(uuid=c['uuid'], body={'properties': props}).execute() {% endcodeblock %} h4. Update the @responsible_person_uuid@ property from X to Y The following code should run with admin privileges, assuming that the managed property is @protected@. {% codeblock as python %} import arvados old_uuid = "zzzzz-tpzed-xxxxxxxxxxxxxxx" new_uuid = "zzzzz-tpzed-yyyyyyyyyyyyyyy" page = 100 offset = 0 cols = [] filters = [['properties.responsible_person_uuid', '=', '{}'.format(old_uuid)]] api = arvados.api() req = api.collections().list(filters=filters, select=['uuid', 'properties'], limit=page).execute() while True: cols += [c for c in req['items']] if req['items_available'] < offset+page: break offset += page req = api.collections().list(filters=filters, select=['uuid', 'properties'], limit=page, offset=offset).execute() print("Found {} collections".format(len(cols))) for c in cols: print("Updating collection {}".format(c["uuid"])) props = c['properties'] props['responsible_person_uuid'] = new_uuid api.collections().update(uuid=c['uuid'], body={'properties': props}).execute() {% endcodeblock %}