def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = initialize_main_variables(client_id) output_objects.append({"object_type": "text", "text": "--------- Trying to STATUS exe ----------"}) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted["unique_resource_name"][-1] exe_name_list = accepted["exe_name"] all = accepted["all"][-1].lower() == "true" parallel = accepted["parallel"][-1].lower() == "true" if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append( { "object_type": "error_text", "text": "Failure: You must be an owner of " + unique_resource_name + " to get status for the exe!", } ) return (output_objects, returnvalues.CLIENT_ERROR) exit_status = returnvalues.OK if all: exe_name_list = get_all_exe_names(unique_resource_name) # take action based on supplied list of exes if len(exe_name_list) == 0: output_objects.append( {"object_type": "text", "text": "No exes specified and 'all' argument not set to true: Nothing to do!"} ) workers = [] task_list = [] for exe_name in exe_name_list: task = Worker( target=status_resource_exe, args=(unique_resource_name, exe_name, configuration.resource_home, logger) ) workers.append((exe_name, [task])) task_list.append(task) throttle_max_concurrent(task_list) task.start() if not parallel: task.join() for (exe_name, task_list) in workers: (status, msg) = task_list[0].finish() output_objects.append({"object_type": "header", "text": "Status exe"}) if not status: output_objects.append({"object_type": "error_text", "text": "Problems getting exe status: %s" % msg}) exit_status = returnvalues.SYSTEM_ERROR else: output_objects.append({"object_type": "text", "text": "Status command run, output: %s" % msg}) return (output_objects, exit_status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) client_dir = client_id_dir(client_id) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) if not correct_handler('POST'): output_objects.append( {'object_type': 'error_text', 'text' : 'Only accepting POST requests to prevent unintended updates'}) return (output_objects, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] resconfig = accepted['resconfig'][-1] output_objects.append({'object_type': 'header', 'text' : 'Trying to Update resource configuration'}) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): logger.error(client_id + ' is not an owner of ' + unique_resource_name + ': update rejected!') output_objects.append({'object_type': 'error_text', 'text' : 'You must be an owner of ' + unique_resource_name + ' to update the configuration!'}) return (output_objects, returnvalues.CLIENT_ERROR) # TODO: race if two confs are uploaded concurrently! host_url, host_identifier = unique_resource_name.rsplit('.', 1) pending_file = os.path.join(configuration.resource_home, unique_resource_name, 'config.tmp') # write new proposed config file to disk try: logger.info('write to file: %s' % pending_file) if not write_file(resconfig, pending_file, logger): output_objects.append({'object_type': 'error_text', 'text': 'Could not write: %s' % pending_file}) return (output_objects, returnvalues.SYSTEM_ERROR) except Exception, err: logger.error('Resource conf %s could not be written: %s' % \ (pending_file, err)) output_objects.append({'object_type': 'error_text', 'text': 'Could not write configuration!'}) return (output_objects, returnvalues.SYSTEM_ERROR)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) output_objects.append({ 'object_type': 'text', 'text': '--------- Trying to get STATUS for frontend ----------' }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] logger.info('%s attempts to get status for frontend at %s', client_id, unique_resource_name) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'You must be an owner of ' + unique_resource_name + ' to get status for the resource frontend!' }) return (output_objects, returnvalues.CLIENT_ERROR) (status, msg) = status_resource(unique_resource_name, configuration.resource_home, logger) if not status: output_objects.append({ 'object_type': 'error_text', 'text': '%s. Error getting resource status.' % msg }) return (output_objects, returnvalues.CLIENT_ERROR) # everything ok output_objects.append({'object_type': 'text', 'text': '%s' % msg}) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """ main """ (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) output_objects.append({'object_type': 'text', 'text' : '--------- Trying to STOP frontend ----------' }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) if not correct_handler('POST'): output_objects.append( {'object_type': 'error_text', 'text' : 'Only accepting POST requests to prevent unintended updates'}) return (output_objects, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] logger.info('%s attempts to stop frontend at %s', client_id, unique_resource_name) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({'object_type': 'error_text', 'text' : 'You must be an owner of ' + unique_resource_name + ' to stop the resource frontend!'}) return (output_objects, returnvalues.CLIENT_ERROR) (status, msg) = stop_resource(unique_resource_name, configuration.resource_home, logger) if not status: output_objects.append({'object_type': 'error_text', 'text' : '%s. Error stopping resource' % msg}) return (output_objects, returnvalues.CLIENT_ERROR) # everything ok output_objects.append({'object_type': 'text', 'text': '%s' % msg}) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'You must be an owner of %s to get the list of owners!' % unique_resource_name }) return (output_objects, returnvalues.CLIENT_ERROR) # is_owner incorporates unique_resource_name verification - no need to # specifically check for illegal directory traversal base_dir = os.path.abspath( os.path.join(configuration.resource_home, unique_resource_name)) + os.sep owners_file = os.path.join(base_dir, 'owners') (list_status, msg) = list_items_in_pickled_list(owners_file, logger) if not list_status: output_objects.append({ 'object_type': 'error_text', 'text': 'Could not get list of owners, reason: %s' % msg }) return (output_objects, returnvalues.SYSTEM_ERROR) output_objects.append({'object_type': 'list', 'list': msg}) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) output_objects.append({'object_type': 'text', 'text' : '--------- Trying to get STATUS for frontend ----------' }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] logger.info('%s attempts to get status for frontend at %s', client_id, unique_resource_name) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({'object_type': 'error_text', 'text' : 'You must be an owner of ' + unique_resource_name + ' to get status for the resource frontend!' }) return (output_objects, returnvalues.CLIENT_ERROR) (status, msg) = status_resource(unique_resource_name, configuration.resource_home, logger) if not status: output_objects.append({'object_type': 'error_text', 'text' : '%s. Error getting resource status.' % msg}) return (output_objects, returnvalues.CLIENT_ERROR) # everything ok output_objects.append({'object_type': 'text', 'text': '%s' % msg}) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = initialize_main_variables(client_id) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted["unique_resource_name"][-1] if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append( { "object_type": "error_text", "text": "You must be an owner of %s to get the list of owners!" % unique_resource_name, } ) return (output_objects, returnvalues.CLIENT_ERROR) # is_owner incorporates unique_resource_name verification - no need to # specifically check for illegal directory traversal base_dir = os.path.abspath(os.path.join(configuration.resource_home, unique_resource_name)) + os.sep owners_file = os.path.join(base_dir, "owners") (status, msg) = list_items_in_pickled_list(owners_file, logger) if not status: output_objects.append({"object_type": "error_text", "text": "Could not get list of owners, reason: %s" % msg}) return (output_objects, returnvalues.SYSTEM_ERROR) output_objects.append({"object_type": "list", "list": msg}) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False, op_title=False, op_menu=client_id) defaults = signature()[1] (validate_status, accepted) = validate_input(user_arguments_dict, defaults, output_objects, allow_rejects=False) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) remote_ip = str(os.getenv('REMOTE_ADDR')) res_type = accepted['type'][-1] unique_resource_name = accepted['unique_resource_name'][-1] exe_name = accepted['exe_name'][-1] status = returnvalues.OK # Web format for cert access and no header for SID access if client_id: output_objects.append({ 'object_type': 'title', 'text': 'Load resource script PGID' }) output_objects.append({ 'object_type': 'header', 'text': 'Load resource script PGID' }) else: output_objects.append({'object_type': 'start'}) # Please note that base_dir must end in slash to avoid access to other # resource dirs when own name is a prefix of another resource name base_dir = os.path.abspath( os.path.join(configuration.resource_home, unique_resource_name)) + os.sep if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append( {'object_type': 'error_text', 'text': "Failure: You must be an owner of '%s' to get the PGID!" % \ unique_resource_name}) return (output_objects, returnvalues.CLIENT_ERROR) # is_owner incorporates unique_resource_name verification - no need to # specifically check for illegal directory traversal on that variable. # exe_name is not automatically checked however - do it manually if not valid_dir_input(base_dir, 'EXE_' + exe_name + '.PGID'): # out of bounds - rogue resource!?!? output_objects.append({ 'object_type': 'error_text', 'text': 'invalid exe_name! %s' % exe_name }) logger.error('''getrespgid called with illegal parameter(s) in what appears to be an illegal directory traversal attempt!: unique_resource_name %s, exe %s, client_id %s''' % (unique_resource_name, exe_name, client_id)) return (output_objects, returnvalues.CLIENT_ERROR) # Check that resource address matches request source to make DoS harder try: check_source_ip(remote_ip, unique_resource_name) except ValueError, vae: output_objects.append({ 'object_type': 'error_text', 'text': 'invalid request: %s' % vae }) logger.error("Invalid put pgid: %s" % vae) return (output_objects, returnvalues.CLIENT_ERROR)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) output_objects.append({'object_type': 'text', 'text' : '--------- Trying to STATUS store ----------' }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] store_name_list = accepted['store_name'] all = accepted['all'][-1].lower() == 'true' parallel = accepted['parallel'][-1].lower() == 'true' if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({'object_type': 'error_text', 'text' : 'Failure: You must be an owner of ' + unique_resource_name + ' to get status for the store!'}) return (output_objects, returnvalues.CLIENT_ERROR) exit_status = returnvalues.OK if all: store_name_list = get_all_store_names(unique_resource_name) # take action based on supplied list of stores if len(store_name_list) == 0: output_objects.append({'object_type': 'text', 'text' : "No stores specified and 'all' argument not set to true: Nothing to do!" }) workers = [] for store_name in store_name_list: task = Worker(target=status_resource_store, args=(unique_resource_name, store_name, configuration.resource_home, logger)) workers.append((store_name, [task])) task.start() if not parallel: task.join() for (store_name, task_list) in workers: (status, msg) = task_list[0].finish() output_objects.append({'object_type': 'header', 'text' : 'Status store'}) if not status: output_objects.append({'object_type': 'error_text', 'text' : 'Problems getting store status: %s' % msg}) exit_status = returnvalues.SYSTEM_ERROR else: output_objects.append({'object_type': 'text', 'text' : 'Status command run, output: %s' % msg}) return (output_objects, exit_status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = initialize_main_variables(client_id) output_objects.append({"object_type": "text", "text": "--------- Trying to Clean store ----------"}) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) if not correct_handler("POST"): output_objects.append( {"object_type": "error_text", "text": "Only accepting POST requests to prevent unintended updates"} ) return (output_objects, returnvalues.CLIENT_ERROR) unique_resource_name = accepted["unique_resource_name"][-1] store_name_list = accepted["store_name"] all = accepted["all"][-1].lower() == "true" parallel = accepted["parallel"][-1].lower() == "true" if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append( { "object_type": "error_text", "text": "Failure: You must be an owner of " + unique_resource_name + " to clean the store!", } ) return (output_objects, returnvalues.CLIENT_ERROR) exit_status = returnvalues.OK if all: store_name_list = get_all_store_names(unique_resource_name) # take action based on supplied list of stores if len(store_name_list) == 0: output_objects.append( {"object_type": "text", "text": "No stores specified and 'all' argument not set to true: Nothing to do!"} ) workers = [] for store_name in store_name_list: task = Worker( target=stop_resource_store, args=(unique_resource_name, store_name, configuration.resource_home, logger) ) workers.append((store_name, [task])) task.start() if not parallel: task.join() # Complete each stop thread before launching corresponding clean threads for (store_name, task_list) in workers: # We could optimize with non-blocking join here but keep it simple for now # as final result will need to wait for slowest member anyway task_list[0].join() task = Worker( target=clean_resource_store, args=(unique_resource_name, store_name, configuration.resource_home, logger) ) task_list.append(task) task.start() if not parallel: task.join() for (store_name, task_list) in workers: (status, msg) = task_list[0].finish() output_objects.append({"object_type": "header", "text": "Clean store output:"}) if not status: output_objects.append( {"object_type": "error_text", "text": "Problems stopping store during clean: %s" % msg} ) (status2, msg2) = task_list[1].finish() if not status2: output_objects.append( {"object_type": "error_text", "text": "Problems cleaning store during clean: %s" % msg2} ) exit_status = returnvalues.SYSTEM_ERROR if status and status2: output_objects.append( {"object_type": "text", "text": "Clean store success: Stop output: %s ; Clean output: %s" % (msg, msg2)} ) return (output_objects, exit_status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] output_objects.append({'object_type': 'header', 'text' : 'Remove Resource Owner'}) (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) if not correct_handler('POST'): output_objects.append( {'object_type': 'error_text', 'text' : 'Only accepting POST requests to prevent unintended updates'}) return (output_objects, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] cert_id = accepted['cert_id'][-1] if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({'object_type': 'error_text', 'text' : 'You must be an owner of %s to remove another owner!' % unique_resource_name}) return (output_objects, returnvalues.CLIENT_ERROR) # is_owner incorporates unique_resource_name verification - no need to # specifically check for illegal directory traversal if not is_user(cert_id, configuration.mig_server_home): output_objects.append({'object_type': 'error_text', 'text' : '%s is not a valid %s user!' % \ (cert_id, configuration.short_title) }) return (output_objects, returnvalues.CLIENT_ERROR) # reject remove if cert_id is not an owner if not resource_is_owner(unique_resource_name, cert_id, configuration): output_objects.append({'object_type': 'error_text', 'text' : '%s is not an owner of %s.' % (cert_id, unique_resource_name)}) return (output_objects, returnvalues.CLIENT_ERROR) base_dir = os.path.abspath(os.path.join(configuration.resource_home, unique_resource_name)) + os.sep # Remove owner owners_file = os.path.join(base_dir, 'owners') (rm_status, rm_msg) = resource_remove_owners(configuration, unique_resource_name, [cert_id]) if not rm_status: output_objects.append({'object_type': 'error_text', 'text' : 'Could not remove owner, reason: %s' % rm_msg}) return (output_objects, returnvalues.SYSTEM_ERROR) output_objects.append({'object_type': 'text', 'text' : '%s was successfully removed and is no longer an owner of %s!' % (cert_id, unique_resource_name)}) output_objects.append({'object_type': 'link', 'destination': 'resadmin.py?unique_resource_name=%s' % \ unique_resource_name, 'class': 'adminlink', 'title': 'Administrate resource', 'text': 'Manage resource'}) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] output_objects.append({ 'object_type': 'header', 'text': 'Reject Resource Request' }) (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1].strip() request_name = unhexlify(accepted['request_name'][-1]) if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'You must be an owner of %s to reject requests!' % unique_resource_name }) return (output_objects, returnvalues.CLIENT_ERROR) # Please note that base_dir must end in slash to avoid access to other # resource dirs when own name is a prefix of another user name base_dir = \ os.path.abspath(os.path.join(configuration.resource_home, unique_resource_name)) + os.sep # IMPORTANT: path must be expanded to abs for proper chrooting abs_path = os.path.abspath(os.path.join(base_dir, request_name)) if not valid_user_path( configuration, abs_path, base_dir, allow_equal=False): logger.warning('%s tried to access restricted path %s ! (%s)' % \ (client_id, abs_path, request_name)) output_objects.append({ 'object_type': 'error_text', 'text': '''Illegal request name "%s": you can only reject requests to your own resources.''' % request_name }) return (output_objects, returnvalues.CLIENT_ERROR) if request_name: request_dir = os.path.join(configuration.resource_home, unique_resource_name) req = load_access_request(configuration, request_dir, request_name) if not req or not delete_access_request(configuration, request_dir, request_name): logger.error("failed to delete owner request for %s in %s" % \ (unique_resource_name, request_name)) output_objects.append({ 'object_type': 'error_text', 'text': 'Failed to remove saved resource request for %s in %s!'\ % (unique_resource_name, request_name)}) return (output_objects, returnvalues.CLIENT_ERROR) output_objects.append({ 'object_type': 'text', 'text': ''' Deleted %(request_type)s access request to %(target)s for %(entity)s . ''' % req }) form_method = 'post' csrf_limit = get_csrf_limit(configuration) fill_helpers = { 'protocol': any_protocol, 'unique_resource_name': unique_resource_name, 'form_method': form_method, 'csrf_field': csrf_field, 'csrf_limit': csrf_limit } fill_helpers.update(req) target_op = 'sendrequestaction' csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) fill_helpers.update({'target_op': target_op, 'csrf_token': csrf_token}) output_objects.append({ 'object_type': 'html_form', 'text': """ <p> You can use the reply form below if you want to additionally send an explanation for rejecting the request. </p> <form method='%(form_method)s' action='%(target_op)s.py'> <input type='hidden' name='%(csrf_field)s' value='%(csrf_token)s' /> <input type=hidden name=request_type value='resourcereject' /> <input type=hidden name=unique_resource_name value='%(target)s' /> <input type=hidden name=cert_id value='%(entity)s' /> <input type=hidden name=protocol value='%(protocol)s' /> <table> <tr> <td class='title'>Optional reject message to requestor(s)</td> </tr><tr> <td><textarea name=request_text cols=72 rows=10> We have decided to reject your %(request_type)s request to our %(target)s resource. Regards, the %(target)s resource owners </textarea></td> </tr> <tr> <td><input type='submit' value='Inform requestor(s)' /></td> </tr> </table> </form> <br /> """ % fill_helpers }) output_objects.append({ 'object_type': 'link', 'destination': 'resadmin.py?unique_resource_name=%s' % unique_resource_name, 'text': 'Back to administration for %s' % unique_resource_name }) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) output_objects.append({ 'object_type': 'text', 'text': '--------- Trying to RESTART frontend ----------' }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] if not configuration.site_enable_resources: output_objects.append({ 'object_type': 'error_text', 'text': '''Resources are not enabled on this system''' }) return (output_objects, returnvalues.SYSTEM_ERROR) if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) logger.info('%s attempts to restart frontend at %s', client_id, unique_resource_name) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'You must be an owner of ' + unique_resource_name + ' to restart the resource frontend!' }) return (output_objects, returnvalues.CLIENT_ERROR) (status, msg) = stop_resource(unique_resource_name, configuration.resource_home, logger) if not status: output_objects.append({ 'object_type': 'error_text', 'text': '%s. Error stopping resource' % msg }) return (output_objects, returnvalues.CLIENT_ERROR) (status, msg2) = start_resource(unique_resource_name, configuration.resource_home, configuration.migserver_https_sid_url, logger) if not status: output_objects.append({ 'object_type': 'error_text', 'text': '%s. Error starting resource' % msg }) return (output_objects, returnvalues.CLIENT_ERROR) # everything ok output_objects.append({ 'object_type': 'text', 'text': 'Stop output: %s ; Start output: %s' % (msg, msg2) }) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Runtime env support' output_objects.append({ 'object_type': 'header', 'text': 'Test runtime environment support' }) client_dir = client_id_dir(client_id) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: logger.warning('%s invalid input: %s' % (op_name, accepted)) return (accepted, returnvalues.CLIENT_ERROR) resource_list = accepted['unique_resource_name'] re_name = accepted['re_name'][-1] status = returnvalues.OK visible_res = user_visible_res_confs(configuration, client_id) if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) if not re_name: output_objects.append({ 'object_type': 'error_text', 'text': 'Please specify the name of the runtime environment!' }) return (output_objects, returnvalues.CLIENT_ERROR) if not valid_dir_input(configuration.re_home, re_name): logger.warning( "possible illegal directory traversal attempt re_name '%s'" % re_name) output_objects.append({ 'object_type': 'error_text', 'text': 'Illegal runtime environment name: "%s"' % re_name }) return (output_objects, returnvalues.CLIENT_ERROR) # Please note that base_dir must end in slash to avoid access to other # user dirs when own name is a prefix of another user name base_dir = os.path.abspath( os.path.join(configuration.user_home, client_dir)) + os.sep for visible_res_name in resource_list: if not visible_res_name in visible_res.keys(): logger.warning('User %s not allowed to view %s (%s)' % \ (client_id, visible_res_name, visible_res.keys())) output_objects.append({'object_type': 'error_text', 'text': 'invalid resource %s' % \ visible_res_name}) status = returnvalues.CLIENT_ERROR continue if not is_owner(client_id, visible_res_name, configuration.resource_home, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'You must be an owner of the resource to validate runtime ' 'environment support. (resource %s)' % visible_res_name }) status = returnvalues.CLIENT_ERROR continue (re_dict, re_msg) = get_re_dict(re_name, configuration) if not re_dict: output_objects.append({ 'object_type': 'error_text', 'text': 'Could not get re_dict %s' % re_msg }) status = returnvalues.SYSTEM_ERROR continue if not testresource_has_re_specified(visible_res_name, re_name, configuration): output_objects.append({ 'object_type': 'error_text', 'text': 'You must specify the runtime environment in the resource' 'configuration before verifying if it is supported!' }) status = returnvalues.CLIENT_ERROR continue base64string = '' for stringpart in re_dict['TESTPROCEDURE']: base64string += stringpart mrslfile_content = base64.decodestring(base64string) try: (filehandle, mrslfile) = tempfile.mkstemp(text=True) os.write(filehandle, mrslfile_content) os.close(filehandle) create_verify_files(['status', 'stdout', 'stderr'], re_name, re_dict, base_dir, logger) except Exception, exc: output_objects.append({ 'object_type': 'error_text', 'text': 'Could not write test job for %s: %s' % (visible_res_name, exc) }) status = returnvalues.SYSTEM_ERROR continue forceddestination_dict = { 'UNIQUE_RESOURCE_NAME': visible_res_name, 'RE_NAME': re_name } (success, msg) = new_job(mrslfile, client_id, configuration, forceddestination_dict) if not success: output_objects.append({ 'object_type': 'error_text', 'text': 'Submit test job failed %s: %s' % (visible_res_name, msg) }) status = returnvalues.SYSTEM_ERROR try: os.remove(mrslfile) except: pass output_objects.append( {'object_type': 'text', 'text': 'Runtime environment test job for %s successfuly submitted! %s' \ % (visible_res_name, msg)})
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) output_objects.append({ 'object_type': 'text', 'text': '--------- Trying to Clean front end ----------' }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'Failure: You must be an owner of ' + unique_resource_name + ' to clean the front end!' }) return (output_objects, returnvalues.CLIENT_ERROR) exit_status = returnvalues.OK (status, msg) = stop_resource_frontend(unique_resource_name, configuration, logger) if not status: output_objects.append({ 'object_type': 'error_text', 'text': 'Problems stopping front end during clean: %s' % msg }) return (output_objects, returnvalues.CLIENT_ERROR) (status2, msg2) = clean_resource_frontend(unique_resource_name, configuration.resource_home, logger) if not status2: output_objects.append({ 'object_type': 'error_text', 'text': 'Problems cleaning front end during clean: %s' % msg2 }) exit_status = returnvalues.SYSTEM_ERROR if status and status2: output_objects.append({ 'object_type': 'text', 'text': 'Clean front end success: Stop output: %s Clean output %s' % (msg, msg2) }) return (output_objects, exit_status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) output_objects.append({ 'object_type': 'text', 'text': '--------- Trying to STATUS exe ----------' }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] exe_name_list = accepted['exe_name'] all = accepted['all'][-1].lower() == 'true' parallel = accepted['parallel'][-1].lower() == 'true' if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'Failure: You must be an owner of ' + unique_resource_name + ' to get status for the exe!' }) return (output_objects, returnvalues.CLIENT_ERROR) exit_status = returnvalues.OK if all: exe_name_list = get_all_exe_names(unique_resource_name) # take action based on supplied list of exes if len(exe_name_list) == 0: output_objects.append({ 'object_type': 'text', 'text': "No exes specified and 'all' argument not set to true: Nothing to do!" }) workers = [] task_list = [] for exe_name in exe_name_list: task = Worker(target=status_resource_exe, args=(unique_resource_name, exe_name, configuration.resource_home, logger)) workers.append((exe_name, [task])) task_list.append(task) throttle_max_concurrent(task_list) task.start() if not parallel: task.join() for (exe_name, task_list) in workers: (status, msg) = task_list[0].finish() output_objects.append({'object_type': 'header', 'text': 'Status exe'}) if not status: output_objects.append({ 'object_type': 'error_text', 'text': 'Problems getting exe status: %s' % msg }) exit_status = returnvalues.SYSTEM_ERROR else: output_objects.append({ 'object_type': 'text', 'text': 'Status command run, output: %s' % msg }) return (output_objects, exit_status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] output_objects.append({'object_type': 'header', 'text' : 'Remove Resource Owner'}) (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] cert_id = accepted['cert_id'][-1] if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append( {'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({'object_type': 'error_text', 'text' : 'You must be an owner of %s to remove another owner!' % unique_resource_name}) return (output_objects, returnvalues.CLIENT_ERROR) # is_owner incorporates unique_resource_name verification - no need to # specifically check for illegal directory traversal if not is_user(cert_id, configuration.mig_server_home): output_objects.append({'object_type': 'error_text', 'text' : '%s is not a valid %s user!' % \ (cert_id, configuration.short_title) }) return (output_objects, returnvalues.CLIENT_ERROR) # reject remove if cert_id is not an owner if not resource_is_owner(unique_resource_name, cert_id, configuration): output_objects.append({'object_type': 'error_text', 'text' : '%s is not an owner of %s.' % (cert_id, unique_resource_name)}) return (output_objects, returnvalues.CLIENT_ERROR) # Remove owner (rm_status, rm_msg) = resource_remove_owners(configuration, unique_resource_name, [cert_id]) if not rm_status: output_objects.append({'object_type': 'error_text', 'text' : 'Could not remove owner, reason: %s' % rm_msg}) return (output_objects, returnvalues.SYSTEM_ERROR) output_objects.append({'object_type': 'text', 'text' : '%s was successfully removed and is no longer an owner of %s!' % (cert_id, unique_resource_name)}) output_objects.append({'object_type': 'link', 'destination': 'resadmin.py?unique_resource_name=%s' % \ unique_resource_name, 'class': 'adminlink iconspace', 'title': 'Administrate resource', 'text': 'Manage resource'}) return (output_objects, returnvalues.OK)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) client_dir = client_id_dir(client_id) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] resconfig = accepted['resconfig'][-1] if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) output_objects.append({ 'object_type': 'header', 'text': 'Trying to Update resource configuration' }) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): logger.error(client_id + ' is not an owner of ' + unique_resource_name + ': update rejected!') output_objects.append({ 'object_type': 'error_text', 'text': 'You must be an owner of ' + unique_resource_name + ' to update the configuration!' }) return (output_objects, returnvalues.CLIENT_ERROR) # TODO: race if two confs are uploaded concurrently! host_url, host_identifier = unique_resource_name.rsplit('.', 1) pending_file = os.path.join(configuration.resource_home, unique_resource_name, 'config.tmp') # write new proposed config file to disk try: logger.info('write to file: %s' % pending_file) if not write_file(resconfig, pending_file, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'Could not write: %s' % pending_file }) return (output_objects, returnvalues.SYSTEM_ERROR) except Exception, err: logger.error('Resource conf %s could not be written: %s' % \ (pending_file, err)) output_objects.append({ 'object_type': 'error_text', 'text': 'Could not write configuration!' }) return (output_objects, returnvalues.SYSTEM_ERROR)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] status = returnvalues.OK output_objects.append({ 'object_type': 'header', 'text': 'Add Resource Owner(s)' }) (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1].strip() cert_id_list = accepted['cert_id'] request_name = unhexlify(accepted['request_name'][-1]) if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'You must be an owner of %s to add a new owner!' % unique_resource_name }) return (output_objects, returnvalues.CLIENT_ERROR) # is_owner incorporates unique_resource_name verification - no need to # specifically check for illegal directory traversal cert_id_added = [] for cert_id in cert_id_list: cert_id = cert_id.strip() if not cert_id: continue if not is_user(cert_id, configuration.mig_server_home): output_objects.append({ 'object_type': 'error_text', 'text': '%s is not a valid %s user!' % (cert_id, configuration.short_title) }) status = returnvalues.CLIENT_ERROR continue # don't add if already an owner if resource_is_owner(unique_resource_name, cert_id, configuration): output_objects.append({ 'object_type': 'error_text', 'text': '%s is already an owner of %s.' % (cert_id, unique_resource_name) }) status = returnvalues.CLIENT_ERROR continue # Add owner (add_status, add_msg) = resource_add_owners(configuration, unique_resource_name, [cert_id]) if not add_status: output_objects.append({ 'object_type': 'error_text', 'text': 'Could not add new owner, reason: %s' % add_msg }) status = returnvalues.SYSTEM_ERROR continue cert_id_added.append(cert_id) if request_name: request_dir = os.path.join(configuration.resource_home, unique_resource_name) if not delete_access_request(configuration, request_dir, request_name): logger.error("failed to delete owner request for %s in %s" % \ (unique_resource_name, request_name)) output_objects.append({ 'object_type': 'error_text', 'text': 'Failed to remove saved request for %s in %s!' % \ (unique_resource_name, request_name)}) if cert_id_added: output_objects.append({ 'object_type': 'html_form', 'text': 'New owner(s)<br/>%s<br/>successfully added to %s!' % ('<br />'.join(cert_id_added), unique_resource_name) }) cert_id_fields = '' for cert_id in cert_id_added: cert_id_fields += """<input type=hidden name=cert_id value='%s' /> """ % cert_id form_method = 'post' csrf_limit = get_csrf_limit(configuration) fill_helpers = { 'res_id': unique_resource_name, 'cert_id_fields': cert_id_fields, 'any_protocol': any_protocol, 'form_method': form_method, 'csrf_field': csrf_field, 'csrf_limit': csrf_limit } target_op = 'sendrequestaction' csrf_token = make_csrf_token(configuration, form_method, target_op, client_id, csrf_limit) fill_helpers.update({'target_op': target_op, 'csrf_token': csrf_token}) output_objects.append({ 'object_type': 'html_form', 'text': """ <form method='%(form_method)s' action='%(target_op)s.py'> <input type='hidden' name='%(csrf_field)s' value='%(csrf_token)s' /> <input type=hidden name=request_type value='resourceaccept' /> <input type=hidden name=unique_resource_name value='%(res_id)s' /> %(cert_id_fields)s <input type=hidden name=protocol value='%(any_protocol)s' /> <table> <tr> <td class='title'>Custom message to user(s)</td> </tr> <tr> <td><textarea name=request_text cols=72 rows=10> We have granted you ownership access to our %(res_id)s resource. You can access the resource administration page from the Resources page. Regards, the %(res_id)s resource owners </textarea></td> </tr> <tr> <td><input type='submit' value='Inform user(s)' /></td> </tr> </table> </form> <br /> """ % fill_helpers }) output_objects.append({'object_type': 'link', 'destination': 'resadmin.py?unique_resource_name=%s' % \ unique_resource_name, 'class': 'adminlink iconspace', 'title': 'Administrate resource', 'text': 'Manage resource'}) return (output_objects, status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False, op_title=False, op_menu=client_id) defaults = signature()[1] (validate_status, accepted) = validate_input(user_arguments_dict, defaults, output_objects, allow_rejects=False) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) remote_ip = str(os.getenv('REMOTE_ADDR')) res_type = accepted['type'][-1] unique_resource_name = accepted['unique_resource_name'][-1] exe_name = accepted['exe_name'][-1] status = returnvalues.OK # Web format for cert access and no header for SID access if client_id: output_objects.append({'object_type': 'title', 'text' : 'Load resource script PGID'}) output_objects.append({'object_type': 'header', 'text' : 'Load resource script PGID'}) else: output_objects.append({'object_type': 'start'}) # Please note that base_dir must end in slash to avoid access to other # resource dirs when own name is a prefix of another resource name base_dir = os.path.abspath(os.path.join(configuration.resource_home, unique_resource_name)) + os.sep if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append( {'object_type': 'error_text', 'text': "Failure: You must be an owner of '%s' to get the PGID!" % \ unique_resource_name}) return (output_objects, returnvalues.CLIENT_ERROR) # is_owner incorporates unique_resource_name verification - no need to # specifically check for illegal directory traversal on that variable. # exe_name is not automatically checked however - do it manually if not valid_dir_input(base_dir, 'EXE_' + exe_name + '.PGID'): # out of bounds - rogue resource!?!? output_objects.append({'object_type': 'error_text', 'text': 'invalid exe_name! %s' % exe_name}) logger.error('''getrespgid called with illegal parameter(s) in what appears to be an illegal directory traversal attempt!: unique_resource_name %s, exe %s, client_id %s''' % (unique_resource_name, exe_name, client_id)) return (output_objects, returnvalues.CLIENT_ERROR) # Check that resource address matches request source to make DoS harder try: check_source_ip(remote_ip, unique_resource_name) except ValueError, vae: output_objects.append({'object_type': 'error_text', 'text': 'invalid request: %s' % vae}) logger.error("Invalid put pgid: %s" % vae) return (output_objects, returnvalues.CLIENT_ERROR)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) output_objects.append({ 'object_type': 'text', 'text': '--------- Trying to RESTART store ----------' }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] store_name_list = accepted['store_name'] all = accepted['all'][-1].lower() == 'true' parallel = accepted['parallel'][-1].lower() == 'true' if not configuration.site_enable_resources: output_objects.append({ 'object_type': 'error_text', 'text': '''Resources are not enabled on this system''' }) return (output_objects, returnvalues.SYSTEM_ERROR) if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'Failure: You must be an owner of ' + unique_resource_name + ' to restart the store!' }) return (output_objects, returnvalues.CLIENT_ERROR) exit_status = returnvalues.OK if all: store_name_list = get_all_store_names(unique_resource_name) # take action based on supplied list of stores if len(store_name_list) == 0: output_objects.append({ 'object_type': 'text', 'text': "No stores specified and 'all' argument not set to true: Nothing to do!" }) workers = [] for store_name in store_name_list: task = Worker(target=stop_resource_store, args=(unique_resource_name, store_name, configuration.resource_home, logger)) workers.append((store_name, [task])) task.start() if not parallel: task.join() # Complete each stop thread before launching corresponding start threads for (store_name, task_list) in workers: # We could optimize with non-blocking join here but keep it simple for now # as final result will need to wait for slowest member anyway task_list[0].join() task = Worker(target=start_resource_store, args=(unique_resource_name, store_name, configuration.resource_home, logger)) task_list.append(task) task.start() if not parallel: task.join() for (store_name, task_list) in workers: (status, msg) = task_list[0].finish() output_objects.append({ 'object_type': 'header', 'text': 'Restart store output:' }) if not status: output_objects.append({ 'object_type': 'error_text', 'text': 'Problems stopping store during restart: %s' % msg }) (status2, msg2) = task_list[1].finish() if not status2: output_objects.append({ 'object_type': 'error_text', 'text': 'Problems starting store during restart: %s' % msg2 }) exit_status = returnvalues.SYSTEM_ERROR if status and status2: output_objects.append({ 'object_type': 'text', 'text': 'Restart store success: Stop output: %s ; Start output: %s' % (msg, msg2) }) return (output_objects, exit_status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) output_objects.append({'object_type': 'text', 'text' : '--------- Trying to RESTART exe ----------' }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) if not correct_handler('POST'): output_objects.append( {'object_type': 'error_text', 'text' : 'Only accepting POST requests to prevent unintended updates'}) return (output_objects, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] cputime = accepted['cputime'][-1] exe_name_list = accepted['exe_name'] all = accepted['all'][-1].lower() == 'true' parallel = accepted['parallel'][-1].lower() == 'true' if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({'object_type': 'error_text', 'text' : 'Failure: You must be an owner of ' + unique_resource_name + ' to restart the exe!'}) return (output_objects, returnvalues.CLIENT_ERROR) exit_status = returnvalues.OK if all: exe_name_list = get_all_exe_names(unique_resource_name) # take action based on supplied list of exes if len(exe_name_list) == 0: output_objects.append({'object_type': 'text', 'text' : "No exes specified and 'all' argument not set to true: Nothing to do!" }) workers = [] task_list = [] for exe_name in exe_name_list: task = Worker(target=stop_resource_exe, args=(unique_resource_name, exe_name, configuration.resource_home, logger)) workers.append((exe_name, [task])) task_list.append(task) throttle_max_concurrent(task_list) task.start() if not parallel: task.join() # Complete each stop thread before launching corresponding start threads for (exe_name, task_list) in workers: # We could optimize with non-blocking join here but keep it simple for now # as final result will need to wait for slowest member anyway task_list[0].join() task = Worker(target=start_resource_exe, args=(unique_resource_name, exe_name, configuration.resource_home, int(cputime), logger)) task_list.append(task) throttle_max_concurrent(task_list) task.start() if not parallel: task.join() for (exe_name, task_list) in workers: (status, msg) = task_list[0].finish() output_objects.append({'object_type': 'header', 'text' : 'Restart exe output:'}) if not status: output_objects.append({'object_type': 'error_text', 'text' : 'Problems stopping exe during restart: %s' % msg}) (status2, msg2) = task_list[1].finish() if not status2: output_objects.append({'object_type': 'error_text', 'text' : 'Problems starting exe during restart: %s' % msg2}) exit_status = returnvalues.SYSTEM_ERROR if status and status2: output_objects.append({'object_type': 'text', 'text' : 'Restart exe success: Stop output: %s ; Start output: %s' % (msg, msg2)}) return (output_objects, exit_status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) title_entry = find_entry(output_objects, 'title') title_entry['text'] = 'Runtime env support' output_objects.append({'object_type': 'header', 'text' : 'Test runtime environment support'}) client_dir = client_id_dir(client_id) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: logger.warning('%s invalid input: %s' % (op_name, accepted)) return (accepted, returnvalues.CLIENT_ERROR) resource_list = accepted['unique_resource_name'] re_name = accepted['re_name'][-1] status = returnvalues.OK visible_res = user_visible_res_confs(configuration, client_id) if not re_name: output_objects.append( {'object_type': 'error_text', 'text' : 'Please specify the name of the runtime environment!'}) return (output_objects, returnvalues.CLIENT_ERROR) if not valid_dir_input(configuration.re_home, re_name): logger.warning( "possible illegal directory traversal attempt re_name '%s'" % re_name) output_objects.append({'object_type': 'error_text', 'text' : 'Illegal runtime environment name: "%s"' % re_name}) return (output_objects, returnvalues.CLIENT_ERROR) # Please note that base_dir must end in slash to avoid access to other # user dirs when own name is a prefix of another user name base_dir = os.path.abspath(os.path.join(configuration.user_home, client_dir)) + os.sep for visible_res_name in resource_list: if not visible_res_name in visible_res.keys(): logger.warning('User %s not allowed to view %s (%s)' % \ (client_id, visible_res_name, visible_res.keys())) output_objects.append({'object_type': 'error_text', 'text': 'invalid resource %s' % \ visible_res_name}) status = returnvalues.CLIENT_ERROR continue if not is_owner(client_id, visible_res_name, configuration.resource_home, logger): output_objects.append( {'object_type': 'error_text', 'text': 'You must be an owner of the resource to validate runtime ' 'environment support. (resource %s)' % visible_res_name}) status = returnvalues.CLIENT_ERROR continue (re_dict, re_msg) = get_re_dict(re_name, configuration) if not re_dict: output_objects.append( {'object_type': 'error_text', 'text': 'Could not get re_dict %s' % re_msg}) status = returnvalues.SYSTEM_ERROR continue if not testresource_has_re_specified(visible_res_name, re_name, configuration): output_objects.append( {'object_type': 'error_text', 'text': 'You must specify the runtime environment in the resource' 'configuration before verifying if it is supported!'}) status = returnvalues.CLIENT_ERROR continue base64string = '' for stringpart in re_dict['TESTPROCEDURE']: base64string += stringpart mrslfile_content = base64.decodestring(base64string) try: (filehandle, mrslfile) = tempfile.mkstemp(text=True) os.write(filehandle, mrslfile_content) os.close(filehandle) create_verify_files(['status', 'stdout', 'stderr'], re_name, re_dict, base_dir, logger) except Exception, exc: output_objects.append( {'object_type': 'error_text', 'text': 'Could not write test job for %s: %s' % (visible_res_name, exc)}) status = returnvalues.SYSTEM_ERROR continue forceddestination_dict = {'UNIQUE_RESOURCE_NAME': visible_res_name, 'RE_NAME': re_name} (success, msg) = new_job(mrslfile, client_id, configuration, forceddestination_dict) if not success: output_objects.append( {'object_type': 'error_text', 'text': 'Submit test job failed %s: %s' % (visible_res_name, msg)}) status = returnvalues.SYSTEM_ERROR try: os.remove(mrslfile) except: pass output_objects.append( {'object_type': 'text', 'text': 'Runtime environment test job for %s successfuly submitted! %s' \ % (visible_res_name, msg)})
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id) output_objects.append({ 'object_type': 'text', 'text': '--------- Trying to STOP store ----------' }) defaults = signature()[1] (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1] store_name_list = accepted['store_name'] all = accepted['all'][-1].lower() == 'true' parallel = accepted['parallel'][-1].lower() == 'true' if not safe_handler(configuration, 'post', op_name, client_id, get_csrf_limit(configuration), accepted): output_objects.append({ 'object_type': 'error_text', 'text': '''Only accepting CSRF-filtered POST requests to prevent unintended updates''' }) return (output_objects, returnvalues.CLIENT_ERROR) if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({ 'object_type': 'error_text', 'text': 'Failure: You must be an owner of ' + unique_resource_name + ' to stop the store!' }) return (output_objects, returnvalues.CLIENT_ERROR) exit_status = returnvalues.OK if all: store_name_list = get_all_store_names(unique_resource_name) # take action based on supplied list of stores if len(store_name_list) == 0: output_objects.append({ 'object_type': 'text', 'text': "No stores specified and 'all' argument not set to true: Nothing to do!" }) workers = [] for store_name in store_name_list: task = Worker(target=stop_resource_store, args=(unique_resource_name, store_name, configuration.resource_home, logger)) workers.append((store_name, [task])) task.start() if not parallel: task.join() for (store_name, task_list) in workers: (status, msg) = task_list[0].finish() output_objects.append({'object_type': 'header', 'text': 'Stop store'}) if not status: output_objects.append({ 'object_type': 'error_text', 'text': 'Problems stopping store: %s' % msg }) exit_status = returnvalues.SYSTEM_ERROR else: output_objects.append({ 'object_type': 'text', 'text': 'Stop store success: %s' % msg }) return (output_objects, exit_status)
def main(client_id, user_arguments_dict): """Main function used by front end""" (configuration, logger, output_objects, op_name) = \ initialize_main_variables(client_id, op_header=False) defaults = signature()[1] output_objects.append({'object_type': 'header', 'text' : 'Add Resource Owner'}) (validate_status, accepted) = validate_input_and_cert( user_arguments_dict, defaults, output_objects, client_id, configuration, allow_rejects=False, ) if not validate_status: return (accepted, returnvalues.CLIENT_ERROR) if not correct_handler('POST'): output_objects.append( {'object_type': 'error_text', 'text' : 'Only accepting POST requests to prevent unintended updates'}) return (output_objects, returnvalues.CLIENT_ERROR) unique_resource_name = accepted['unique_resource_name'][-1].strip() cert_id = accepted['cert_id'][-1].strip() if not is_owner(client_id, unique_resource_name, configuration.resource_home, logger): output_objects.append({'object_type': 'error_text', 'text' : 'You must be an owner of %s to add a new owner!' % unique_resource_name}) return (output_objects, returnvalues.CLIENT_ERROR) # is_owner incorporates unique_resource_name verification - no need to # specifically check for illegal directory traversal if not is_user(cert_id, configuration.mig_server_home): output_objects.append({'object_type': 'error_text', 'text' : '%s is not a valid %s user!' % (cert_id, configuration.short_title)}) return (output_objects, returnvalues.CLIENT_ERROR) # don't add if already an owner if resource_is_owner(unique_resource_name, cert_id, configuration): output_objects.append({'object_type': 'error_text', 'text' : '%s is already an owner of %s.' % (cert_id, unique_resource_name)}) return (output_objects, returnvalues.CLIENT_ERROR) # Please note that base_dir must end in slash to avoid access to other # resource dirs when own name is a prefix of another user name base_dir = \ os.path.abspath(os.path.join(configuration.resource_home, unique_resource_name)) + os.sep # Add owner (add_status, add_msg) = resource_add_owners(configuration, unique_resource_name, [cert_id]) if not add_status: output_objects.append({'object_type': 'error_text', 'text' : 'Could not add new owner, reason: %s' % add_msg}) return (output_objects, returnvalues.SYSTEM_ERROR) output_objects.append({'object_type': 'text', 'text' : 'New owner %s successfully added to %s!' % (cert_id, unique_resource_name)}) output_objects.append({'object_type': 'html_form', 'text' : """ <form method='post' action='sendrequestaction.py'> <input type=hidden name=request_type value='resourceaccept' /> <input type=hidden name=unique_resource_name value='%s' /> <input type=hidden name=cert_id value='%s' /> <input type=hidden name=protocol value='%s' /> <table> <tr> <td class='title'>Custom message to user</td> </tr> <tr> <td><textarea name=request_text cols=72 rows=10> We have granted you ownership access to our %s resource. You can access the resource administration page from the Resources page. Regards, the %s resource owners </textarea></td> </tr> <tr> <td><input type='submit' value='Inform user' /></td> </tr> </table> </form> <br /> """ % (unique_resource_name, cert_id, any_protocol, unique_resource_name, unique_resource_name)}) output_objects.append({'object_type': 'link', 'destination': 'resadmin.py?unique_resource_name=%s' % \ unique_resource_name, 'class': 'adminlink', 'title': 'Administrate resource', 'text': 'Manage resource'}) return (output_objects, returnvalues.OK)