def irods_obj_getacls(path, verbose=False): """ This function returns a list of ACLs associated with the input iRODS data object. Each ACL consists of a 'user:access' pair, where access is the same as that used in the ichmod command. None is returned if an error occurred. """ if not path: return None acl_list = [] acl_query = "select DATA_ACCESS_NAME, DATA_ACCESS_USER_ID where DATA_NAME = '%s'" output = run_iquest(acl_query % (path,), format='%s:%s', verbose=verbose) if output == None: return None for line in output.splitlines(): access, user_id = line.split(':') if access.startswith('read'): access = 'read' elif access.startswith('modify'): access = 'write' user_name = irods_id_to_user(user_id, verbose=verbose) acl_list.append([user_name, access]) return acl_list
def irods_user_to_id(username, verbose=None): """ Look up a user in the iRODS user DB and return the user identifier (a number). If the user isn't found, return an empty string. If an error occurs, return None. username should be in the form 'user#zone' Note: this also works for looking up groups. """ if not username: return None user = username.split('#', 1) if len(user) != 2: if verbose: print('irods_user_to_id: username should be of form "user#zone"') return None id_query = "select USER_ID where USER_NAME = '%s' and USER_ZONE = '%s'" % (user[0], user[1]) id = run_iquest(id_query, format='%s', verbose=verbose) if id == None: return None elif not id: # user not found return "" else: # keep in string form, as this is what iRODS mostly works with return id.rstrip('\n')
def get_irods_group_membership(zone): """ Retrieves the IDS users and groups from iRODS. Only group names starting with 'ids-' are retrieved. Input: if 'zone' is provided, its the name of the remote zone for iquest. Returns: a dict where the key is the group name, and the value is a list of users who are members of the group. """ query = "select USER_GROUP_NAME, USER_NAME where USER_GROUP_NAME like 'ids-%'" output = run_iquest(query, format='%s:%s', zone=zone) if output == None: # some error occurred return None group_list = {} for line in output.splitlines(): if line.startswith('Zone is'): continue group, user = line.split(':') if not group == user: if group in group_list: group_list[group].append(user) else: group_list[group] = [ user, ] elif group not in group_list: group_list[group] = [] # empty group return group_list
def get_resource_details(resource_name=None, verbose=False): """ This function will retrieve the details of all the resources defined within the local zone. If resource_name is provided, only the details for that resource will be returned. Returns a dict of dicts, where the key of the top-level dict is the resource name, and the sub-dict contains the resource details including: type, endpoint, comment, and creation and modification timestamps. Will return None if some error occurred. """ sep = '~_~' query_fields = [ 'RESC_NAME', 'RESC_ZONE_NAME', 'RESC_TYPE_NAME', 'RESC_CLASS_NAME', 'RESC_LOC', 'RESC_VAULT_PATH', 'RESC_STATUS', 'RESC_INFO', 'RESC_COMMENT', 'RESC_CREATE_TIME', 'RESC_MODIFY_TIME', ] query_format = sep.join(['%s'] * len(query_fields)) query = 'select %s' % (','.join(query_fields)) if resource_name: query = query + " where RESC_NAME = '%s'" % (resource_name,) output = run_iquest(query, format=query_format, verbose=verbose) if not output: return None resources = {} for line in output.splitlines(): fields = line.split(sep) resource = { 'zone_name': fields[1], 'type': fields[2], 'class': fields[3], 'server': fields[4], 'vault_path': fields[5], 'status': fields[6], 'info': fields[7], 'comment': fields[8], 'create_time': fields[9], 'modification_time': fields[10], } resources[fields[0]] = resource return resources
def get_zone_list(verbose=False): """ This function retrieves a list of all the zones within the IDS. Returns a list sorted by zone name, or None if some error occurred. """ output = run_iquest('select order(ZONE_NAME)', format='%s', verbose=verbose) if not output: return None return [zone.rstrip('\n') for zone in output.splitlines()]
def get_local_zone(verbose=False): """ This function retrieves the name of the local zone using an iquest query. Returns the name of the local zone, or None if some error occurred. """ zname = run_iquest("select ZONE_NAME where ZONE_TYPE = 'local'", format='%s', verbose=verbose) if zname == None: return None return zname.rstrip('\n')
def get_resource_list(verbose=False): """ This function retrieves a list of all the resources within the local zone. Returns a list sorted by resource name, or None if some error occurred. """ output = run_iquest('select order(RESC_NAME)', format='%s', verbose=verbose) if not output: return None return [resource.rstrip('\n') for resource in output.splitlines()]
def get_irods_group(groupname, verbose=False): """ Return the list of members of the provided group, or the empty list if there are no members. If an error occurs, return None. """ if not groupname: return None group_query = "select USER_NAME, USER_ZONE where USER_GROUP_NAME = '%s'" output = run_iquest(group_query % (groupname,), format='%s#%s', verbose=verbose) if output == None: return None return output.splitlines()
def get_zone_details(zone_name=None, verbose=False): """ This function will retrieve the details of all the zones defined within the IDS. If zone_name is provided, only the details for that zone will be returned. Returns a array of dicts with each array element representing a zone, and the dict contains the zone details including: name, type, endpoint, comment, and creation and modification timestamps. Will return None if some error occurred. """ sep = '~_~' query_fields = [ 'ZONE_NAME', 'ZONE_TYPE', 'ZONE_CONNECTION', 'ZONE_COMMENT', 'ZONE_CREATE_TIME', 'ZONE_MODIFY_TIME', ] query_format = sep.join(['%s'] * len(query_fields)) query = 'select %s' % (','.join(query_fields)) if zone_name: query = query + " where ZONE_NAME = '%s'" % (zone_name,) output = run_iquest(query, format=query_format, verbose=verbose) if output is None: return None zones = [] for line in output.splitlines(): fields = line.split(sep) zone = { 'zone_name': fields[0], 'type': fields[1], 'connection': fields[2], 'comment': fields[3], 'create_time': fields[4], 'modification_time': fields[5], } zones.append(zone) return zones
def irods_user_exists(username, verbose=False): """ Check if a particular user exists in iRODS. Returns 1 if yes, and 0 if no, and -1 if some error occurred. """ if not username: return -1 user = username.split('#', 1) if len(user) != 2: if verbose: print('irods_user_to_id: username should be of form "user#zone"') return -1 user_query = "select count(USER_NAME) where USER_NAME = '%s' and USER_ZONE = '%s'" exists = run_iquest(user_query % (user[0], user[1]), format='%s', verbose=verbose) if exists == None: return -1 else: return int(exists)
def irods_obj_exists(obj, verbose=False): """ This function checks whether the provided data object name 'obj' exists in the iRODS namespace. Returns 1 if yes, and 0 if not, and -1 if some error occurred during the lookup. Note: a 0 return just means the path isn't a data object. There could still be a collection with the same path name. """ if not obj: return -1 obj_query = "select count(DATA_NAME) where DATA_NAME = '%s'" % (obj,) exists = run_iquest(obj_query, format='%s', verbose=verbose) if exists == None: return -1 return int(exists)
def irods_coll_exists(coll, verbose=False): """ This function checks whether the provided collection name 'coll' exists in the iRODS namespace. Returns 1 if yes, and 0 if not, and -1 if some error occurred during the lookup. Note: a 0 return just means the path isn't a collection. There could still be a data object with the same path name. """ if not coll: return -1 coll_query = "select count(COLL_NAME) where COLL_NAME = '%s'" % (coll,) exists = run_iquest(coll_query, format='%s', verbose=verbose) if exists == None: return -1 return int(exists)
def irods_id_to_user(id, zone=None, verbose=None): """ Look up a user id in the iRODS user DB and return the user name. If the user isn't found, return an empty string. If an error occurs, return None. the username returned is in the form 'user#zone' Note: this also works for looking up groups. """ if not id: return None if not zone: zone = get_local_zone(verbose) if not zone: return None # lookup user id in the cache first if zone in user_id_cache: if id in user_id_cache[zone]: return user_id_cache[zone][id] # no cache hit ... look it up user_query = "select USER_NAME, USER_ZONE where USER_ID = '%s'" % (id,) user = run_iquest(user_query, format='%s#%s', zone=zone, verbose=verbose) if user == None: return None elif not user: # user not found return "" else: # keep in string form, as this is what iRODS mostly works with user_name = user.rstrip('\n') if zone not in user_id_cache: user_id_cache[zone] = {} user_id_cache[zone][id] = user_name return user_name