File indexing completed on 2026-04-10 08:39:00
0001 from typing import Dict
0002
0003 from pandacommon.pandalogger.LogWrapper import LogWrapper
0004 from pandacommon.pandalogger.PandaLogger import PandaLogger
0005
0006 from pandaserver.api.v1.common import (
0007 extract_primary_production_working_group,
0008 extract_production_working_groups,
0009 generate_response,
0010 get_dn,
0011 get_email_address,
0012 get_fqan,
0013 has_production_role,
0014 request_validation,
0015 )
0016 from pandaserver.config import panda_config
0017 from pandaserver.srvcore.CoreUtils import clean_user_id
0018 from pandaserver.srvcore.panda_request import PandaRequest
0019
0020 _logger = PandaLogger().getLogger("api_system")
0021
0022
0023 @request_validation(_logger, secure=True, request_method="GET")
0024 def get_attributes(req: PandaRequest, **kwargs: dict) -> Dict:
0025 """
0026 Get attributes
0027
0028 Gets all parameters and environment variables.
0029
0030 API details:
0031 HTTP Method: GET
0032 Path: /v1/system/get_attributes
0033
0034 Args:
0035 req(PandaRequest): internally generated request object containing the env variables
0036 **kwargs(dict): arbitrary keyword parameters that will be printed out
0037
0038 Returns:
0039 dict: The system response `{"success": success, "message": message, "data": data}`.
0040 When successful, the message field contains a string with all the attributes.
0041 """
0042 tmp_logger = LogWrapper(_logger, "get_attributes")
0043 tmp_logger.debug("Start")
0044
0045
0046 parameter_dictionary = {key: str(value) for key, value in sorted(kwargs.items())}
0047 parameter_section = "===== param =====\n" + "\n".join(f"{key} = {value}" for key, value in parameter_dictionary.items())
0048
0049
0050 environment_dictionary = {key: str(req.subprocess_env[key]) for key in sorted(req.subprocess_env)}
0051 environment_section = "\n====== env ======\n" + "\n".join(f"{key} : {value}" for key, value in environment_dictionary.items())
0052
0053
0054 text_representation = parameter_section + "\n" + environment_section + "\n"
0055
0056
0057 combined_data = {"parameters": parameter_dictionary, "environment": environment_dictionary}
0058 tmp_logger.debug("Done")
0059 return generate_response(True, text_representation, combined_data)
0060
0061
0062 @request_validation(_logger, secure=True, request_method="GET")
0063 def get_voms_attributes(req: PandaRequest) -> Dict:
0064 """
0065 Get VOMS attributes
0066
0067 Gets the VOMS attributes (i.e. the ones starting with GRST) in sorted order. Requires a secure connection.
0068
0069 API details:
0070 HTTP Method: GET
0071 Path: /v1/system/get_voms_attributes
0072
0073 Args:
0074 req(PandaRequest): internally generated request object containing the env variables
0075
0076 Returns:
0077 dict: The system response with text representation and dictionary of attributes.
0078 Example: `{"success": True, "message": "<formatted string>", "data": {"key": "value"}}`
0079 """
0080 tmp_logger = LogWrapper(_logger, "get_voms_attributes")
0081 tmp_logger.debug("Start")
0082
0083
0084 attributes = {}
0085 for tmp_key, tmp_value in req.subprocess_env.items():
0086 if tmp_key.startswith("GRST_CRED_"):
0087 attributes[tmp_key] = tmp_value
0088
0089
0090 text_representation = "\n".join(f"{key} : {value}" for key, value in sorted(attributes.items()))
0091
0092 tmp_logger.debug("Done")
0093 return generate_response(True, text_representation, attributes)
0094
0095
0096 @request_validation(_logger, secure=True, request_method="GET")
0097 def get_user_attributes(req: PandaRequest) -> Dict:
0098 """
0099 Get user attributes
0100
0101 Gets user attributes as seen by PanDA for debug purposes. Requires a secure connection.
0102
0103 API details:
0104 HTTP Method: GET
0105 Path: /v1/system/get_user_attributes
0106
0107 Args:
0108 req(PandaRequest): internally generated request object containing the env variables
0109
0110 Returns:
0111 dict: The system response `{"success": success, "message": message, "data": data}`.
0112 When successful, the message field contains a string with the user attributes,
0113 and the data field contains the dictionary representation.
0114 """
0115 tmp_logger = LogWrapper(_logger, "get_user_attributes")
0116 tmp_logger.debug("Start")
0117
0118
0119 user_raw = req.subprocess_env["SSL_CLIENT_S_DN"]
0120
0121
0122 user_bare = get_dn(req)
0123
0124
0125 user_clean = clean_user_id(user_raw)
0126
0127
0128 fqans = get_fqan(req)
0129
0130
0131 email_address = get_email_address(user_clean, tmp_logger)
0132
0133
0134 is_production_user = has_production_role(req)
0135
0136
0137 production_working_groups = extract_production_working_groups(fqans)
0138
0139
0140 primary_working_group = extract_primary_production_working_group(fqans)
0141
0142
0143 text_representation = (
0144 f"User DN (raw): {user_raw}\nUser DN (bare): {user_bare}\nUser DN (clean): {user_clean}\n"
0145 f"Email address: {email_address}\n"
0146 f"FQANs: {fqans}\nProduction user: {is_production_user}\n"
0147 f"Production working groups: {production_working_groups}\nPrimary production working group: {primary_working_group}\n"
0148 )
0149 dictionary_representation = {
0150 "user_dn_raw": user_raw,
0151 "user_dn_clean": user_clean,
0152 "fqans": fqans,
0153 "is_production_user": is_production_user,
0154 "production_working_groups": production_working_groups,
0155 "primary_working_group": primary_working_group,
0156 }
0157
0158 tmp_logger.debug(text_representation)
0159
0160 tmp_logger.debug("Done")
0161 return generate_response(True, text_representation, dictionary_representation)
0162
0163
0164 @request_validation(_logger, secure=False, request_method="GET")
0165 def is_alive(req: PandaRequest) -> Dict:
0166 """
0167 Is alive
0168
0169 Check if the server is alive. Basic function for the health check used in SLS monitoring.
0170
0171 API details:
0172 HTTP Method: GET
0173 Path: /v1/system/is_alive
0174
0175 Args:
0176 req(PandaRequest): internally generated request object containing the env variables
0177
0178 Returns:
0179 dict: The system response with the name of the endpoint
0180 Example: `{"success": True}`
0181 """
0182 tmp_logger = LogWrapper(_logger, "is_alive")
0183 tmp_logger.debug("Start")
0184 tmp_logger.debug("Done")
0185
0186 return generate_response(True)