def server_edit(hostname): db_session = DBSession() server = get_server(db_session, hostname) if server is None: abort(404) form = ServerForm(request.form) if request.method == 'POST' and form.validate(): if not can_edit(current_user): abort(401) if hostname != form.hostname.data and get_server( db_session, form.hostname.data) is not None: return render_template('server/edit.html', form=form, duplicate_error=True) create_or_update_server_repository( db_session=db_session, hostname=form.hostname.data, server_type=form.server_type.data, server_url=form.server_url.data, username=form.username.data, password=form.password.data if len(form.password.data) > 0 else server.password, vrf=form.vrf.data if form.server_type.data == ServerType.TFTP_SERVER or form.server_type.data == ServerType.FTP_SERVER else '', server_directory=form.server_directory.data, destination_on_host=form.destination_on_host.data, created_by=current_user.username, server=server) return redirect(url_for('home')) else: # Assign the values to form fields form.hostname.data = server.hostname form.server_type.data = server.server_type form.server_url.data = server.server_url form.username.data = server.username form.vrf.data = server.vrf form.server_directory.data = server.server_directory form.destination_on_host.data = server.destination_on_host if not is_empty(server.password): form.password_placeholder = 'Use Password on File' else: form.password_placeholder = 'No Password Specified' return render_template('server/edit.html', form=form)
def api_get_server_repositories(request): validate_url_parameters(request, [KEY_HOSTNAME]) rows = [] db_session = DBSession() hostname = request.args.get(KEY_HOSTNAME) if hostname: server = get_server(db_session, hostname) if server is None: raise ValueError("Server repository '{}' does not exist in the database.".format(hostname)) servers = [server] else: servers = get_server_list(db_session) for server in servers: if server is not None: row = dict() row[KEY_HOSTNAME] = server.hostname row[KEY_SERVER_TYPE] = server.server_type for req in params_dict[server.server_type]: row[req] = server.__getattribute__(req) if server.__getattribute__(req) is not None else '' row[server_url_dict[server.server_type]] = server.server_url if not is_empty(server_directory_dict[server.server_type]): row[server_directory_dict[server.server_type]] = server.server_directory rows.append(row) return jsonify(**{RESPONSE_ENVELOPE: {'server_repository_list': rows}})
def server_create(): if not can_create(current_user): abort(401) form = ServerForm(request.form) if request.method == 'POST' and form.validate(): db_session = DBSession() server = get_server(db_session, form.hostname.data) if server is not None: return render_template('server/edit.html', form=form, duplicate_error=True) create_or_update_server_repository( db_session=db_session, hostname=form.hostname.data, server_type=form.server_type.data, server_url=form.server_url.data, username=form.username.data, password=form.password.data, vrf=form.vrf.data if form.server_type.data == ServerType.TFTP_SERVER or form.server_type.data == ServerType.FTP_SERVER else '', server_directory=form.server_directory.data, destination_on_host=form.destination_on_host.data, created_by=current_user.username) return redirect(url_for('home')) return render_template('server/edit.html', form=form)
def get_penguins(cpps=None, server=None, shape=None): servers = common.get_json("servers") shapes = common.get_json("shapes") try: cpps = common.get_cpps(servers, cpps) server = common.get_server(servers, cpps, server) shape = get_shape(shapes, shape) except (KeyboardInterrupt, EOFError): raise common.LoginError() logger = logging.getLogger() logger.addHandler(logging.NullHandler()) clients_offsets = [(common.get_client(servers, cpps, server, logger), int(offset["x"]), int(offset["y"])) for offset in shape["offsets"]] return cpps, server, shape, clients_offsets
def api_get_server_repositories(request): validate_url_parameters(request, [KEY_HOSTNAME]) rows = [] db_session = DBSession() hostname = request.args.get(KEY_HOSTNAME) if hostname: server = get_server(db_session, hostname) if server is None: raise ValueError( "Server repository '{}' does not exist in the database.". format(hostname)) servers = [server] else: servers = get_server_list(db_session) for server in servers: if server is not None: row = dict() row[KEY_HOSTNAME] = server.hostname row[KEY_SERVER_TYPE] = server.server_type for req in params_dict[server.server_type]: row[req] = server.__getattribute__( req) if server.__getattribute__(req) is not None else '' row[server_url_dict[server.server_type]] = server.server_url if not is_empty(server_directory_dict[server.server_type]): row[server_directory_dict[ server.server_type]] = server.server_directory rows.append(row) return jsonify(**{RESPONSE_ENVELOPE: {'server_repository_list': rows}})
def check_server_reachability(): if not can_check_reachability(current_user): abort(401) hostname = request.args.get('hostname') server_type = request.args.get('server_type') server_url = request.args.get('server_url') username = request.args.get('username') password = request.args.get('password') server_directory = request.args.get('server_directory') server = Server(hostname=hostname, server_type=server_type, server_url=server_url, username=username, password=password, server_directory=server_directory) # The form is in the edit mode and the user clicks Validate Reachability # If there is no password specified, try get it from the database. if (server_type == ServerType.FTP_SERVER or server_type == ServerType.SFTP_SERVER or server_type == ServerType.SCP_SERVER) and password == '': db_session = DBSession() server_in_db = get_server(db_session, hostname) if server_in_db is not None: server.password = server_in_db.password server_impl = get_server_impl(server) is_reachable, error = server_impl.check_reachability() if is_reachable: return jsonify({'status': 'OK'}) else: return jsonify({'status': error})
def api_create_server_repositories(request): """ [{ "hostname": "Repository_1", "server_type": "TFTP", "tftp_server_path": "223.255.254.245", "home_directory": "/auto/tftp-sjc-users1" },{ "hostname": "Repository_2", "server_type": "FTP", "server_address": "172.27.153.150", "home_directory": "/tftpboot" },{ "hostname": "Repository_3", "server_type": "SFTP", "server_address": "nb-server3", "home_directory": "/auto/tftp-vista" }] """ rows = [] db_session = DBSession() error_found = False json_list = convert_json_request_to_list(request) for data in json_list: row = dict() try: validate_required_keys_in_dict(data, [KEY_HOSTNAME, KEY_SERVER_TYPE]) hostname = get_acceptable_string(data[KEY_HOSTNAME]) row[KEY_HOSTNAME] = hostname if len(hostname) == 0: raise ValueError("Server repository name '{}' is not valid.".format(data[KEY_HOSTNAME])) server_type = data.get(KEY_SERVER_TYPE) if server_type not in [ServerType.TFTP_SERVER, ServerType.FTP_SERVER, ServerType.SFTP_SERVER, ServerType.LOCAL_SERVER, ServerType.SCP_SERVER]: raise ValueError("'{}' is not a supported server type.".format(server_type)) row[KEY_SERVER_TYPE] = server_type validate_required_keys_in_dict(data, required_keys_dict[server_type]) validate_acceptable_keys_in_dict(data, acceptable_keys_dict[server_type]) server = get_server(db_session, hostname) if server is None: # These are the required fields for a new server repository creation. validate_required_keys_in_dict(data, required_keys_dict.get(server_type)) server_url = data.get(server_url_dict[server_type]) server_url = server_url if server_url is not None else \ (None if server is None else server.server_url) server_directory = data.get(server_directory_dict[server_type]) server_directory = server_directory if server_directory is not None else \ (None if server is None else server.server_directory) vrf = data.get(KEY_VRF) if data.get(KEY_VRF) is not None else \ (None if server is None else server.vrf) username = data.get(KEY_USERNAME) if data.get(KEY_USERNAME) is not None else \ (None if server is None else server.username) password = data.get(KEY_PASSWORD) if data.get(KEY_PASSWORD) is not None else \ (None if server is None else server.password) destination_on_host = data.get(KEY_DESTINATION_ON_HOST) if data.get(KEY_DESTINATION_ON_HOST) is not None else \ (None if server is None else server.destination_on_host) create_or_update_server_repository(db_session, hostname=hostname, server_type=server_type, server_url=server_url, username=username, password=password, vrf=vrf, server_directory=server_directory, destination_on_host=destination_on_host, created_by=g.api_user.username, server=get_server(db_session, hostname)) row[RESPONSE_STATUS] = APIStatus.SUCCESS except Exception as e: row[RESPONSE_STATUS] = APIStatus.FAILED row[RESPONSE_STATUS_MESSAGE] = e.message error_found = True rows.append(row) return jsonify(**{RESPONSE_ENVELOPE: {'server_repository_list': rows}}), (HTTP_OK if not error_found else HTTP_MULTI_STATUS_ERROR)
def api_create_install_request(request): """ Install Action: Pre-Upgrade, Post-Upgrade, and Commit POST: http://localhost:5000/api/v1/install BODY: [ {'hostname': 'My Host', 'install_action': 'Post-Upgrade', 'scheduled_time': '05-02-2016 08:00 AM', 'command_profile': 'Edge Devices', 'dependency': 'Add'} ] Install Action: Add BODY: [ {'hostname': 'My Host', 'install_action': 'Add', 'scheduled_time': '05-02-2016 08:00 AM', 'server_repository': 'My FTP Server', 'software_packages': ['asr9k-px-5.3.3.CSCuz05961.pie, asr9k-px-5.3.3.CSCux89921.pie], 'dependency': 'Pre-Upgrade'} ] Install Action: Activate, Remove, Deactivate BODY: [ {'hostname': 'My Host', 'install_action': 'Activate', 'scheduled_time': '05-02-2016 08:00 AM', 'software_packages': ['asr9k-px-5.3.3.CSCuz05961.pie, asr9k-px-5.3.3.CSCux89921.pie] 'dependency': '101'} ] RETURN: {"api_response": { "install_job_list": [ {"status": "SUCCESS", "hostname": "My Host", "id": 101}, {"status": "FAILED", "hostname": "My Host 2", "status_message": "Unable to locate host"} ] } } """ rows = [] error_found = False db_session = DBSession() custom_command_profile_dict = get_custom_command_profile_name_to_id_dict(db_session) # ---------------------------- first phase is to attempt the data validation ---------------------------- # entries = [] json_list = convert_json_request_to_list(request) for data in json_list: row = dict() try: validate_required_keys_in_dict(data, [KEY_INSTALL_ACTION]) install_action = data[KEY_INSTALL_ACTION] if install_action not in supported_install_actions: raise ValueError("'{}' is an invalid install action.".format(install_action)) validate_acceptable_keys_in_dict(data, acceptable_keys) validate_required_keys_in_dict(data, required_keys_dict[install_action]) hostname = data[KEY_HOSTNAME] host = get_host(db_session, hostname) if host is None: raise ValueError("'{}' is an invalid hostname.".format(data[KEY_HOSTNAME])) if KEY_SERVER_REPOSITORY in data.keys(): server = get_server(db_session, data[KEY_SERVER_REPOSITORY]) if server is None: raise ValueError("'{}' is an invalid server repository.".format(data[KEY_SERVER_REPOSITORY])) if KEY_CUSTOM_COMMAND_PROFILE in data.keys(): custom_command_profile_names = convert_value_to_list(data, KEY_CUSTOM_COMMAND_PROFILE) for custom_command_profile_name in custom_command_profile_names: custom_command_profile_id = custom_command_profile_dict.get(custom_command_profile_name) if custom_command_profile_id is None: raise ValueError("'{}' is an invalid custom command profile.".format(custom_command_profile_name)) if KEY_SOFTWARE_PACKAGES in data.keys() and is_empty(data[KEY_SOFTWARE_PACKAGES]): raise ValueError("Software packages when specified cannot be empty.") # Check time fields and validate their values if KEY_SCHEDULED_TIME not in data.keys(): row[KEY_UTC_SCHEDULED_TIME] = datetime.utcnow() elif KEY_UTC_OFFSET not in data.keys(): raise ValueError("Missing utc_offset. If scheduled_time is submitted, utc_offset is also required.") elif not verify_utc_offset(data[KEY_UTC_OFFSET]): raise ValueError("Invalid utc_offset: Must be in '<+|->dd:dd' format and be between -12:00 and +14:00.") else: try: time = datetime.strptime(data[KEY_SCHEDULED_TIME], "%m-%d-%Y %I:%M %p") row[KEY_UTC_SCHEDULED_TIME] = get_utc_time(time, data[KEY_UTC_OFFSET]) except ValueError: raise ValueError("Invalid scheduled_time: {} must be in 'mm-dd-yyyy hh:mm AM|PM' format.". format(data[KEY_SCHEDULED_TIME])) # Handle duplicate entry. It is defined by the hostname and install_action pair. if (hostname, install_action) not in entries: entries.append((hostname, install_action)) else: raise ValueError("More than one entry with the same hostname: '{}' and install_action: '{}'. " "Remove any duplicate and resubmit.".format(hostname, install_action)) except Exception as e: row[RESPONSE_STATUS] = APIStatus.FAILED row[RESPONSE_STATUS_MESSAGE] = e.message error_found = True # Add the original key value pairs to the new array. for key in data.keys(): row[key] = data[key] rows.append(row) # End of loop if error_found: for row in rows: if RESPONSE_STATUS not in row.keys(): row[RESPONSE_STATUS] = APIStatus.FAILED row[RESPONSE_STATUS_MESSAGE] = 'Not submitted. Check other jobs for error message.' if KEY_UTC_SCHEDULED_TIME in row.keys(): row.pop(KEY_UTC_SCHEDULED_TIME) return jsonify(**{RESPONSE_ENVELOPE: {KEY_INSTALL_JOB_LIST: rows}}), HTTP_BAD_REQUEST # ---------------------------- Second phase is to attempt the job creation ---------------------------- # sorted_list = sorted(rows, cmp=get_key) rows = [] error_found = False implicit_dependency_list = {} for install_request in sorted_list: row = dict() try: hostname = install_request[KEY_HOSTNAME] install_action = install_request[KEY_INSTALL_ACTION] row[KEY_INSTALL_ACTION] = install_action row[KEY_HOSTNAME] = hostname host_id = get_host(db_session, hostname).id utc_scheduled_time = install_request[KEY_UTC_SCHEDULED_TIME].strftime("%m/%d/%Y %I:%M %p") server_id = -1 if KEY_SERVER_REPOSITORY in install_request.keys(): server = get_server(db_session, install_request[KEY_SERVER_REPOSITORY]) if server is not None: server_id = server.id server_directory = '' if KEY_SERVER_DIRECTORY in install_request.keys(): server_directory = install_request[KEY_SERVER_DIRECTORY] software_packages = [] if KEY_SOFTWARE_PACKAGES in install_request.keys(): software_packages = install_request[KEY_SOFTWARE_PACKAGES] custom_command_profile_ids = [] if KEY_CUSTOM_COMMAND_PROFILE in install_request.keys(): custom_command_profile_names = convert_value_to_list(install_request, KEY_CUSTOM_COMMAND_PROFILE) for custom_command_profile_name in custom_command_profile_names: custom_command_profile_id = custom_command_profile_dict.get(custom_command_profile_name) if custom_command_profile_id is not None: custom_command_profile_ids.append(str(custom_command_profile_id)) install_job = create_or_update_install_job(db_session, host_id=host_id, install_action=install_action, scheduled_time=utc_scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, custom_command_profile_ids=custom_command_profile_ids, dependency=get_dependency_id(db_session, implicit_dependency_list, install_request, host_id), created_by=g.api_user.username) row[KEY_ID] = install_job.id if install_action in ordered_install_actions: if hostname not in implicit_dependency_list: implicit_dependency_list[hostname] = [] implicit_dependency_list[hostname].append((install_job.id, install_action, install_request[KEY_UTC_SCHEDULED_TIME])) row[RESPONSE_STATUS] = APIStatus.SUCCESS except Exception as e: row[RESPONSE_STATUS] = APIStatus.FAILED row[RESPONSE_STATUS_MESSAGE] = e.message row[RESPONSE_TRACE] = traceback.format_exc() error_found = True rows.append(row) return jsonify(**{RESPONSE_ENVELOPE: {KEY_INSTALL_JOB_LIST: rows}}), (HTTP_OK if not error_found else HTTP_MULTI_STATUS_ERROR)
def api_create_server_repositories(request): """ [{ "hostname": "Repository_1", "server_type": "TFTP", "tftp_server_path": "223.255.254.245", "home_directory": "/auto/tftp-sjc-users1" },{ "hostname": "Repository_2", "server_type": "FTP", "server_address": "172.27.153.150", "home_directory": "/tftpboot" },{ "hostname": "Repository_3", "server_type": "SFTP", "server_address": "nb-server3", "home_directory": "/auto/tftp-vista" }] """ rows = [] db_session = DBSession() error_found = False json_list = convert_json_request_to_list(request) for data in json_list: row = dict() try: validate_required_keys_in_dict(data, [KEY_HOSTNAME, KEY_SERVER_TYPE]) hostname = get_acceptable_string(data[KEY_HOSTNAME]) row[KEY_HOSTNAME] = hostname if len(hostname) == 0: raise ValueError( "Server repository name '{}' is not valid.".format( data[KEY_HOSTNAME])) server_type = data.get(KEY_SERVER_TYPE) if server_type not in [ ServerType.TFTP_SERVER, ServerType.FTP_SERVER, ServerType.SFTP_SERVER, ServerType.LOCAL_SERVER, ServerType.SCP_SERVER ]: raise ValueError( "'{}' is not a supported server type.".format(server_type)) row[KEY_SERVER_TYPE] = server_type validate_required_keys_in_dict(data, required_keys_dict[server_type]) validate_acceptable_keys_in_dict(data, acceptable_keys_dict[server_type]) server = get_server(db_session, hostname) if server is None: # These are the required fields for a new server repository creation. validate_required_keys_in_dict( data, required_keys_dict.get(server_type)) server_url = data.get(server_url_dict[server_type]) server_url = server_url if server_url is not None else \ (None if server is None else server.server_url) server_directory = data.get(server_directory_dict[server_type]) server_directory = server_directory if server_directory is not None else \ (None if server is None else server.server_directory) vrf = data.get(KEY_VRF) if data.get(KEY_VRF) is not None else \ (None if server is None else server.vrf) username = data.get(KEY_USERNAME) if data.get(KEY_USERNAME) is not None else \ (None if server is None else server.username) password = data.get(KEY_PASSWORD) if data.get(KEY_PASSWORD) is not None else \ (None if server is None else server.password) destination_on_host = data.get(KEY_DESTINATION_ON_HOST) if data.get(KEY_DESTINATION_ON_HOST) is not None else \ (None if server is None else server.destination_on_host) create_or_update_server_repository( db_session, hostname=hostname, server_type=server_type, server_url=server_url, username=username, password=password, vrf=vrf, server_directory=server_directory, destination_on_host=destination_on_host, created_by=g.api_user.username, server=get_server(db_session, hostname)) row[RESPONSE_STATUS] = APIStatus.SUCCESS except Exception as e: row[RESPONSE_STATUS] = APIStatus.FAILED row[RESPONSE_STATUS_MESSAGE] = e.message error_found = True rows.append(row) return jsonify(**{RESPONSE_ENVELOPE: { 'server_repository_list': rows }}), (HTTP_OK if not error_found else HTTP_MULTI_STATUS_ERROR)
def api_create_install_request(request): """ Install Action: Pre-Upgrade, Post-Upgrade, and Commit POST: http://localhost:5000/api/v1/install BODY: [ {'hostname': 'My Host', 'install_action': 'Post-Upgrade', 'scheduled_time': '05-02-2016 08:00 AM', 'command_profile': 'Edge Devices', 'dependency': 'Add'} ] Install Action: Add BODY: [ {'hostname': 'My Host', 'install_action': 'Add', 'scheduled_time': '05-02-2016 08:00 AM', 'server_repository': 'My FTP Server', 'software_packages': ['asr9k-px-5.3.3.CSCuz05961.pie, asr9k-px-5.3.3.CSCux89921.pie], 'dependency': 'Pre-Upgrade'} ] Install Action: Activate, Remove, Deactivate BODY: [ {'hostname': 'My Host', 'install_action': 'Activate', 'scheduled_time': '05-02-2016 08:00 AM', 'software_packages': ['asr9k-px-5.3.3.CSCuz05961.pie, asr9k-px-5.3.3.CSCux89921.pie] 'dependency': '101'} ] RETURN: {"api_response": { "install_job_list": [ {"status": "SUCCESS", "hostname": "My Host", "id": 101}, {"status": "FAILED", "hostname": "My Host 2", "status_message": "Unable to locate host"} ] } } """ rows = [] error_found = False db_session = DBSession() custom_command_profile_dict = get_custom_command_profile_name_to_id_dict( db_session) # ---------------------------- first phase is to attempt the data validation ---------------------------- # entries = [] json_list = convert_json_request_to_list(request) for data in json_list: row = dict() try: validate_required_keys_in_dict(data, [KEY_INSTALL_ACTION]) install_action = data[KEY_INSTALL_ACTION] if install_action not in supported_install_actions: raise ValueError("'{}' is an invalid install action.".format( install_action)) validate_acceptable_keys_in_dict(data, acceptable_keys) validate_required_keys_in_dict(data, required_keys_dict[install_action]) hostname = data[KEY_HOSTNAME] host = get_host(db_session, hostname) if host is None: raise ValueError("'{}' is an invalid hostname.".format( data[KEY_HOSTNAME])) if KEY_SERVER_REPOSITORY in data.keys(): server = get_server(db_session, data[KEY_SERVER_REPOSITORY]) if server is None: raise ValueError( "'{}' is an invalid server repository.".format( data[KEY_SERVER_REPOSITORY])) if KEY_CUSTOM_COMMAND_PROFILE in data.keys(): custom_command_profile_names = convert_value_to_list( data, KEY_CUSTOM_COMMAND_PROFILE) for custom_command_profile_name in custom_command_profile_names: custom_command_profile_id = custom_command_profile_dict.get( custom_command_profile_name) if custom_command_profile_id is None: raise ValueError( "'{}' is an invalid custom command profile.". format(custom_command_profile_name)) if KEY_SOFTWARE_PACKAGES in data.keys() and is_empty( data[KEY_SOFTWARE_PACKAGES]): raise ValueError( "Software packages when specified cannot be empty.") # Check time fields and validate their values if KEY_SCHEDULED_TIME not in data.keys(): row[KEY_UTC_SCHEDULED_TIME] = datetime.utcnow() elif KEY_UTC_OFFSET not in data.keys(): raise ValueError( "Missing utc_offset. If scheduled_time is submitted, utc_offset is also required." ) elif not verify_utc_offset(data[KEY_UTC_OFFSET]): raise ValueError( "Invalid utc_offset: Must be in '<+|->dd:dd' format and be between -12:00 and +14:00." ) else: try: time = datetime.strptime(data[KEY_SCHEDULED_TIME], "%m-%d-%Y %I:%M %p") row[KEY_UTC_SCHEDULED_TIME] = get_utc_time( time, data[KEY_UTC_OFFSET]) except ValueError: raise ValueError( "Invalid scheduled_time: {} must be in 'mm-dd-yyyy hh:mm AM|PM' format." .format(data[KEY_SCHEDULED_TIME])) # Handle duplicate entry. It is defined by the hostname and install_action pair. if (hostname, install_action) not in entries: entries.append((hostname, install_action)) else: raise ValueError( "More than one entry with the same hostname: '{}' and install_action: '{}'. " "Remove any duplicate and resubmit.".format( hostname, install_action)) except Exception as e: row[RESPONSE_STATUS] = APIStatus.FAILED row[RESPONSE_STATUS_MESSAGE] = e.message error_found = True # Add the original key value pairs to the new array. for key in data.keys(): row[key] = data[key] rows.append(row) # End of loop if error_found: for row in rows: if RESPONSE_STATUS not in row.keys(): row[RESPONSE_STATUS] = APIStatus.FAILED row[RESPONSE_STATUS_MESSAGE] = 'Not submitted. Check other jobs for error message.' if KEY_UTC_SCHEDULED_TIME in row.keys(): row.pop(KEY_UTC_SCHEDULED_TIME) return jsonify(**{RESPONSE_ENVELOPE: { KEY_INSTALL_JOB_LIST: rows }}), HTTP_BAD_REQUEST # ---------------------------- Second phase is to attempt the job creation ---------------------------- # sorted_list = sorted(rows, cmp=get_key) rows = [] error_found = False implicit_dependency_list = {} for install_request in sorted_list: row = dict() try: hostname = install_request[KEY_HOSTNAME] install_action = install_request[KEY_INSTALL_ACTION] row[KEY_INSTALL_ACTION] = install_action row[KEY_HOSTNAME] = hostname host_id = get_host(db_session, hostname).id utc_scheduled_time = install_request[ KEY_UTC_SCHEDULED_TIME].strftime("%m/%d/%Y %I:%M %p") server_id = -1 if KEY_SERVER_REPOSITORY in install_request.keys(): server = get_server(db_session, install_request[KEY_SERVER_REPOSITORY]) if server is not None: server_id = server.id server_directory = '' if KEY_SERVER_DIRECTORY in install_request.keys(): server_directory = install_request[KEY_SERVER_DIRECTORY] software_packages = [] if KEY_SOFTWARE_PACKAGES in install_request.keys(): software_packages = install_request[KEY_SOFTWARE_PACKAGES] custom_command_profile_ids = [] if KEY_CUSTOM_COMMAND_PROFILE in install_request.keys(): custom_command_profile_names = convert_value_to_list( install_request, KEY_CUSTOM_COMMAND_PROFILE) for custom_command_profile_name in custom_command_profile_names: custom_command_profile_id = custom_command_profile_dict.get( custom_command_profile_name) if custom_command_profile_id is not None: custom_command_profile_ids.append( str(custom_command_profile_id)) install_job = create_or_update_install_job( db_session, host_id=host_id, install_action=install_action, scheduled_time=utc_scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, custom_command_profile_ids=custom_command_profile_ids, dependency=get_dependency_id(db_session, implicit_dependency_list, install_request, host_id), created_by=g.api_user.username) row[KEY_ID] = install_job.id if install_action in ordered_install_actions: if hostname not in implicit_dependency_list: implicit_dependency_list[hostname] = [] implicit_dependency_list[hostname].append( (install_job.id, install_action, install_request[KEY_UTC_SCHEDULED_TIME])) row[RESPONSE_STATUS] = APIStatus.SUCCESS except Exception as e: row[RESPONSE_STATUS] = APIStatus.FAILED row[RESPONSE_STATUS_MESSAGE] = e.message row[RESPONSE_TRACE] = traceback.format_exc() error_found = True rows.append(row) return jsonify(**{RESPONSE_ENVELOPE: { KEY_INSTALL_JOB_LIST: rows }}), (HTTP_OK if not error_found else HTTP_MULTI_STATUS_ERROR)