""" This Service provides functionality to access and modify the InstalledComponentsDB database """ from __future__ import absolute_import from __future__ import division from __future__ import print_function import six from DIRAC import S_OK, S_ERROR, gLogger from DIRAC.FrameworkSystem.DB.InstalledComponentsDB import ( InstalledComponentsDB, Component, Host, InstalledComponent, HostLogging, ) from DIRAC.Core.DISET.RequestHandler import RequestHandler __RCSID__ = "45ddde113 (2021-10-01 11:19:55 +0200) Chris Burr " class ComponentMonitoringHandler(RequestHandler): @classmethod def initializeHandler(cls, serviceInfo): """ Handler class initialization """ ComponentMonitoringHandler.doCommit = True try: ComponentMonitoringHandler.db = InstalledComponentsDB() except Exception as e: gLogger.error("Could not connect to the database", ": %s" % (e)) return S_ERROR("Could not connect to the database") return S_OK("Initialization went well") def __joinInstallationMatch(self, installationFields, componentFields, hostFields): matchFields = installationFields for key in componentFields: matchFields["Component." + key] = componentFields[key] for key in hostFields: matchFields["Host." + key] = hostFields[key] return S_OK(matchFields) types_addComponent = [dict] def export_addComponent(self, component): """ Creates a new Component object on the database component argument should be a dictionary with the Component fields and its values """ return ComponentMonitoringHandler.db.addComponent(component) types_componentExists = [dict] def export_componentExists(self, matchFields): """ Returns whether components matching the given criteria exist matchFields argument should be a dictionary with the fields to match matchFields accepts fields of the form and to filter using > and < relationships. """ return ComponentMonitoringHandler.db.exists(Component, matchFields) types_getComponents = [dict, bool, bool] def export_getComponents(self, matchFields, includeInstallations, includeHosts): """ Returns a list of all the Components in the database matchFields argument should be a dictionary with the fields to match or empty to get all the instances matchFields also accepts fields of the form and to filter using > and < relationships includeInstallations indicates whether data about the installations in which the components takes part is to be retrieved includeHosts (only if includeInstallations is set to True) indicates whether data about the host in which there are instances of this component is to be retrieved """ return ComponentMonitoringHandler.db.getComponents(matchFields, includeInstallations, includeHosts) types_updateComponents = [dict, dict] def export_updateComponents(self, matchFields, updates): """ Updates Components objects on the database matchFields argument should be a dictionary with the fields to match (instances matching the fields will be updated) or empty to update all the instances matchFields also accepts fields of the form and to filter using > and < relationships updates argument updates should be a dictionary with the Component fields and their new updated values """ return ComponentMonitoringHandler.db.updateComponents(matchFields, updates) types_removeComponents = [dict] def export_removeComponents(self, matchFields): """ Removes from the database components that match the given fields matchFields argument should be a dictionary with the fields to match or empty to remove all the instances matchFields also accepts fields of the form and to filter using > and < relationships """ return ComponentMonitoringHandler.db.removeComponents(matchFields) types_addHost = [dict] def export_addHost(self, host): """ Creates a new Host object on the database host argument should be a dictionary with the Host fields and its values """ return ComponentMonitoringHandler.db.addHost(host) types_hostExists = [dict] def export_hostExists(self, matchFields): """ Returns whether hosts matching the given criteria exist matchFields argument should be a dictionary with the fields to match matchFields also accepts fields of the form and to filter using > and < relationships """ return ComponentMonitoringHandler.db.exists(Host, matchFields) types_getHosts = [dict, bool, bool] def export_getHosts(self, matchFields, includeInstallations, includeComponents): """ Returns a list of all the Hosts in the database matchFields argument should be a dictionary with the fields to match or empty to get all the instances matchFields also accepts fields of the form and to filter using > and < relationships includeInstallations indicates whether data about the installations in which the host takes part is to be retrieved includeComponents (only if includeInstallations is set to True) indicates whether data about the components installed into this host is to be retrieved """ return ComponentMonitoringHandler.db.getHosts(matchFields, includeInstallations, includeComponents) types_updateHosts = [dict, dict] def export_updateHosts(self, matchFields, updates): """ Updates Hosts objects on the database matchFields argument should be a dictionary with the fields to match (instances matching the fields will be updated) or empty to update all the instances matchFields also accepts fields of the form and to filter using > and < relationships updates argument should be a dictionary with the Host fields and their new updated values updates argument should be a dictionary with the Host fields and their new updated values """ return ComponentMonitoringHandler.db.updateHosts(matchFields, updates) types_removeHosts = [dict] def export_removeHosts(self, matchFields): """ Removes from the database hosts that match the given fields matchFields argument should be a dictionary with the fields to match or empty to remove all the instances matchFields also accepts fields of the form and to filter using > and < relationships """ return ComponentMonitoringHandler.db.removeHosts(matchFields) types_addInstallation = [dict, dict, dict, bool] def export_addInstallation(self, installation, componentDict, hostDict, forceCreate): """ Creates a new InstalledComponent object on the database installation argument should be a dictionary with the InstalledComponent fields and its values componentDict argument should be a dictionary with the Component fields and its values hostDict argument should be a dictionary with the Host fields and its values forceCreate indicates whether a new Component and/or Host should be created if the given ones do not exist """ return ComponentMonitoringHandler.db.addInstalledComponent(installation, componentDict, hostDict, forceCreate) types_installationExists = [dict, dict, dict] def export_installationExists(self, installationFields, componentFields, hostFields): """ Returns whether installations matching the given criteria exist installationFields argument should be a dictionary with the fields to match for the installation componentFields argument should be a dictionary with the fields to match for the component installed hostFields argument should be a dictionary with the fields to match for the host where the installation is made """ matchFields = self.__joinInstallationMatch(installationFields, componentFields, hostFields)["Value"] return ComponentMonitoringHandler.db.exists(InstalledComponent, matchFields) types_getInstallations = [dict, dict, dict, bool] def export_getInstallations(self, installationFields, componentFields, hostFields, installationsInfo): """ Returns a list of installations matching the given criteria installationFields argument should be a dictionary with the fields to match for the installation componentFields argument should be a dictionary with the fields to match for the component installed hostFields argument should be a dictionary with the fields to match for the host where the installation is made installationsInfo indicates whether information about the components and host taking part in the installation is to be provided """ matchFields = self.__joinInstallationMatch(installationFields, componentFields, hostFields)["Value"] return ComponentMonitoringHandler.db.getInstalledComponents(matchFields, installationsInfo) types_updateInstallations = [dict, dict, dict, dict] def export_updateInstallations(self, installationFields, componentFields, hostFields, updates): """ Updates installations matching the given criteria installationFields argument should be a dictionary with the fields to match for the installation componentFields argument should be a dictionary with the fields to match for the component installed or empty to update regardless of component hostFields argument should be a dictionary with the fields to match for the host where the installation is made or empty to update regardless of host updates argument should be a dictionary with the Installation fields and their new updated values """ matchFields = self.__joinInstallationMatch(installationFields, componentFields, hostFields)["Value"] return ComponentMonitoringHandler.db.updateInstalledComponents(matchFields, updates) types_removeInstallations = [dict, dict, dict] def export_removeInstallations(self, installationFields, componentFields, hostFields): """ Removes installations matching the given criteria installationFields argument should be a dictionary with the fields to match for the installation componentFields argument should be a dictionary with the fields to match for the component installed hostFields argument should be a dictionary with the fields to match for the host where the installation is made """ matchFields = self.__joinInstallationMatch(installationFields, componentFields, hostFields)["Value"] return ComponentMonitoringHandler.db.removeInstalledComponents(matchFields) types_updateLog = [six.string_types, dict] def export_updateLog(self, host, fields): """ Updates the log entry for a given host in the database with the given fields host is the name of the machine to which the logging information belongs fields is a dictionary where the fields contain the logging information to be stored in the database """ result = ComponentMonitoringHandler.db.exists(HostLogging, {"hostName": host}) if not result["OK"]: return result if result["Value"]: result = ComponentMonitoringHandler.db.updateLogs({"hostName": host}, fields) else: fields["hostName"] = host result = ComponentMonitoringHandler.db.addLog(fields) if not result["OK"]: return result return S_OK("Logs updated correctly") types_getLog = [six.string_types] def export_getLog(self, host): """ Retrieves the logging information currently stored for the given host """ result = ComponentMonitoringHandler.db.exists(HostLogging, {"hostName": host}) if not result["OK"]: return result if not result["Value"]: return S_ERROR("Host %s does not exist" % host) return ComponentMonitoringHandler.db.getLogs({"hostName": host}) types_getLogs = [] def export_getLogs(self): """ Retrieves the logging information currently stored for all hosts """ return ComponentMonitoringHandler.db.getLogs() types_removeLogs = [dict] def export_removeLogs(self, fields): """ Deletes all the matching logging information fields is a dictionary containing the values for the fields such that any matching entries in the database should be deleted """ result = ComponentMonitoringHandler.db.exists(HostLogging, fields) if not result["OK"]: return result if not result["Value"]: return S_ERROR("Host does not exist") return ComponentMonitoringHandler.db.removeLogs(fields)