""" The Grid module contains several utilities for grid operations """ from __future__ import absolute_import from __future__ import division from __future__ import print_function import six import os import re from DIRAC.Core.Utilities.Os import sourceEnv from DIRAC.FrameworkSystem.Client.ProxyManagerClient import gProxyManager from DIRAC.Core.Security.ProxyInfo import getProxyInfo from DIRAC.ConfigurationSystem.Client.Helpers import Local from DIRAC.Core.Utilities.ReturnValues import S_OK, S_ERROR from DIRAC.Core.Utilities.Subprocess import systemCall, shellCall __RCSID__ = "45ddde113 (2021-10-01 11:19:55 +0200) Chris Burr " def executeGridCommand(proxy, cmd, gridEnvScript=None): """ Execute cmd tuple after sourcing GridEnv """ currentEnv = dict(os.environ) if not gridEnvScript: # if not passed as argument, use default from CS Helpers gridEnvScript = Local.gridEnv() if gridEnvScript: command = gridEnvScript.split() ret = sourceEnv(10, command) if not ret["OK"]: return S_ERROR("Failed sourcing GridEnv: %s" % ret["Message"]) gridEnv = ret["outputEnv"] # # Preserve some current settings if they are there # if "X509_VOMS_DIR" in currentEnv: gridEnv["X509_VOMS_DIR"] = currentEnv["X509_VOMS_DIR"] if "X509_CERT_DIR" in currentEnv: gridEnv["X509_CERT_DIR"] = currentEnv["X509_CERT_DIR"] else: gridEnv = currentEnv if not proxy: res = getProxyInfo() if not res["OK"]: return res gridEnv["X509_USER_PROXY"] = res["Value"]["path"] elif isinstance(proxy, six.string_types): if os.path.exists(proxy): gridEnv["X509_USER_PROXY"] = proxy else: return S_ERROR("Can not treat proxy passed as a string") else: ret = gProxyManager.dumpProxyToFile(proxy) if not ret["OK"]: return ret gridEnv["X509_USER_PROXY"] = ret["Value"] result = systemCall(120, cmd, env=gridEnv) return result def ldapsearchBDII(filt=None, attr=None, host=None, base=None, selectionString="Glue"): """Python wrapper for ldapserch at bdii. :param filt: Filter used to search ldap, default = '', means select all :param attr: Attributes returned by ldapsearch, default = '*', means return all :param host: Host used for ldapsearch, default = 'cclcgtopbdii01.in2p3.fr:2170', can be changed by $LCG_GFAL_INFOSYS :return: standard DIRAC answer with Value equals to list of ldapsearch responses Each element of list is dictionary with keys: 'dn': Distinguished name of ldapsearch response 'objectClass': List of classes in response 'attr': Dictionary of attributes """ if filt is None: filt = "" if attr is None: attr = "" if host is None: host = "cclcgtopbdii01.in2p3.fr:2170" if base is None: base = "Mds-Vo-name=local,o=grid" if isinstance(attr, list): attr = " ".join(attr) cmd = 'ldapsearch -x -LLL -o ldif-wrap=no -h %s -b %s "%s" %s' % (host, base, filt, attr) result = shellCall(0, cmd) response = [] if not result["OK"]: return result status = result["Value"][0] stdout = result["Value"][1] stderr = result["Value"][2] if status != 0: return S_ERROR(stderr) lines = [] for line in stdout.split("\n"): if line.find(" ") == 0: lines[-1] += line.strip() else: lines.append(line.strip()) record = None for line in lines: if line.find("dn:") == 0: record = { "dn": line.replace("dn:", "").strip(), "objectClass": [], "attr": {"dn": line.replace("dn:", "").strip()}, } response.append(record) continue if record: if line.find("objectClass:") == 0: record["objectClass"].append(line.replace("objectClass:", "").strip()) continue if line.find(selectionString) == 0: index = line.find(":") if index > 0: attr = line[:index] value = line[index + 1 :].strip() if attr in record["attr"]: if isinstance(record["attr"][attr], list): record["attr"][attr].append(value) else: record["attr"][attr] = [record["attr"][attr], value] else: record["attr"][attr] = value return S_OK(response)