def api_get_host_packages_by_states(hostname): """ Returns the software packages that satisfy the requested package states (e.g. 'active,committed') """ package_state = request.args.get('package_state') db_session = DBSession() host = get_host(db_session, hostname) rows = [] if host is not None: # It is possible that package_state contains a commas delimited state list. # In this case, the union of those packages will be used. package_states = package_state.split(',') packages = [] for package_state in package_states: packages_list = db_session.query(Package).filter( and_(Package.host_id == host.id, Package.state == package_state)).order_by( Package.name).all() if len(packages_list) > 0: packages.extend(packages_list) for package in packages: rows.append({ 'package': package.name if package.location is None else package.location + ':' + package.name }) return jsonify(**{'data': rows})
def delete_all_installations_for_host(hostname, status=None): if not can_delete_install(current_user): abort(401) db_session = DBSession() host = get_host(db_session, hostname) if host is None: abort(404) try: install_jobs = db_session.query(InstallJob).filter( InstallJob.host_id == host.id, InstallJob.status == status).all() if not install_jobs: return jsonify(status="No record fits the delete criteria.") for install_job in install_jobs: db_session.delete(install_job) if status == JobStatus.FAILED: delete_install_job_dependencies(db_session, install_job.id) db_session.commit() return jsonify({'status': 'OK'}) except: logger.exception('delete_install_job() hit exception') return jsonify({'status': 'Failed: check system logs for details'})
def api_create_install_jobs(): db_session = DBSession() hostname = request.form['hostname'] install_action = request.form.getlist('install_action[]') scheduled_time = request.form['scheduled_time_UTC'] software_packages = request.form['software_packages'] server = request.form['server'] server_directory = request.form['server_directory'] pending_downloads = request.form['pending_downloads'] custom_command_profiles = request.form['custom_command_profile'] host = get_host(db_session, hostname) try: # The dependency on each install action is already indicated in the implicit ordering in the selector. # If the user selected Pre-Upgrade and Install Add, Install Add (successor) will # have Pre-Upgrade (predecessor) as the dependency. dependency = 0 for one_install_action in install_action: new_install_job = create_or_update_install_job(db_session=db_session, host_id=host.id, install_action=one_install_action, scheduled_time=scheduled_time, software_packages=software_packages, server=server, server_directory=server_directory, pending_downloads=pending_downloads, custom_command_profile=custom_command_profiles, dependency=dependency) dependency = new_install_job.id return jsonify({'status': 'OK'}) except Exception: return jsonify({'status': 'Failed'})
def check_host_reachability(): if not can_check_reachability(current_user): abort(401) urls = [] # Below information is directly from the page and # may not have been saved yet. hostname = request.args.get('hostname') platform = request.args.get('platform') host_or_ip = request.args.get('host_or_ip') username = request.args.get('username') password = request.args.get('password') enable_password = request.args.get('enable_password') connection_type = request.args.get('connection_type') port_number = request.args.get('port_number') jump_host_id = request.args.get('jump_host') # If a jump host exists, create the connection URL if int(jump_host_id) > 0: db_session = DBSession() jump_host = get_jump_host_by_id(db_session=db_session, id=jump_host_id) if jump_host is not None: url = make_url(connection_type=jump_host.connection_type, host_username=jump_host.username, host_password=jump_host.password, host_or_ip=jump_host.host_or_ip, port_number=jump_host.port_number) urls.append(url) db_session = DBSession() # The form is in the edit mode and the user clicks Validate Reachability # If there is no password specified, get it from the database. if is_empty(password) or is_empty(enable_password): host = get_host(db_session, hostname) if host is not None: password = host.connection_param[0].password enable_password = host.connection_param[0].enable_password system_option = SystemOption.get(db_session) if system_option.enable_default_host_authentication: if not is_empty(system_option.default_host_username) and not is_empty( system_option.default_host_password): if system_option.default_host_authentication_choice == DefaultHostAuthenticationChoice.ALL_HOSTS or \ (system_option.default_host_authentication_choice == DefaultHostAuthenticationChoice.HOSTS_WITH_NO_SPECIFIED_USERNAME_AND_PASSWORD and is_empty(username) and is_empty(password)): username = system_option.default_host_username password = system_option.default_host_password url = make_url(connection_type=connection_type, host_username=username, host_password=password, host_or_ip=host_or_ip, port_number=port_number, enable_password=enable_password) urls.append(url) return jsonify({'status': 'OK'}) if is_connection_valid( hostname, urls) else jsonify({'status': 'Failed'})
def get_dependencies(): db_session = DBSession() hostnames = request.args.get('hosts', '', type=str).split(',') dependency = request.args.get('dependency', '', type=str) dependency_list = [] disqualified_count = 0 for hostname in hostnames: host = get_host(db_session, hostname) if host and host.connection_param[0] and ( not host.connection_param[0].port_number): disqualified_count += 1 dependency_list.append('-2') continue if dependency: # Firstly, check if dependency action is scheduled or in progress, if so, add dependency last_unfinished_dependency_job = get_last_unfinished_install_action( db_session, dependency, get_host(db_session, hostname).id) if last_unfinished_dependency_job: dependency_list.append(last_unfinished_dependency_job.id) else: # Secondly, check if dependency action most recently completed or failed last_completed_or_failed_dependency_job = get_last_completed_or_failed_install_action( db_session, dependency, host.id) if last_completed_or_failed_dependency_job: if last_completed_or_failed_dependency_job.status == JobStatus.COMPLETED: dependency_list.append('-1') else: dependency_list.append( last_completed_or_failed_dependency_job. install_job_id) else: disqualified_count += 1 dependency_list.append('-2') else: dependency_list.append('-1') return jsonify( **{ 'data': [{ 'dependency_list': dependency_list, 'disqualified_count': disqualified_count }] })
def api_get_servers_by_hostname(hostname): db_session = DBSession() host = get_host(db_session, hostname) if host is not None: return api_get_servers_by_region(host.region_id) return jsonify(**{'data': []})
def api_get_host_dashboard_packages(hostname, package_state): db_session = DBSession() host = get_host(db_session, hostname) rows = [] if host is not None: # It is possible that package_state contains a commas delimited state list. # In this case, the union of those packages will be used. package_states = package_state.split(',') packages = [] for package_state in package_states: packages_list = db_session.query(Package).filter( and_(Package.host_id == host.id, Package.state == package_state)).order_by( Package.name).all() if len(packages_list) > 0: packages.extend(packages_list) has_module_packages = False for package in packages: if len(package.modules_package_state) > 0: has_module_packages = True break if has_module_packages: module_package_dict = {} # Format it from module, then packages for package in packages: package_name = package.name if package.location is None else package.location + ':' + package.name for modules_package_state in package.modules_package_state: module = modules_package_state.module_name if module in module_package_dict: module_package_dict[module].append(package_name) else: package_list = [] package_list.append(package_name) module_package_dict[module] = package_list sorted_dict = collections.OrderedDict( sorted(module_package_dict.items())) for module in sorted_dict: package_list = sorted_dict[module] rows.append({'package': module}) for package_name in package_list: rows.append({'package': (' ' * 7) + package_name}) else: for package in packages: rows.append({ 'package': package.name if package.location is None else package.location + ':' + package.name }) return jsonify(**{'data': rows})
def api_get_inventory(hostname): rows = [] dt_params = DataTableParams(request) db_session = DBSession() host = get_host(db_session, hostname) if not host: abort(404) clauses = [] if len(dt_params.search_value): criteria = '%' + dt_params.search_value + '%' clauses.append(HostInventory.location.like(criteria)) clauses.append(HostInventory.model_name.like(criteria)) clauses.append(HostInventory.name.like(criteria)) clauses.append(HostInventory.description.like(criteria)) clauses.append(HostInventory.serial_number.like(criteria)) clauses.append(HostInventory.hardware_revision.like(criteria)) query = db_session.query(HostInventory)\ .join(Host, Host.id == HostInventory.host_id) total_count = query.filter(HostInventory.host_id == host.id).count() filtered_count = query.filter(and_(HostInventory.host_id == host.id), or_(*clauses)).count() columns = [ getattr(HostInventory.location, dt_params.sort_order)(), getattr(HostInventory.model_name, dt_params.sort_order)(), getattr(HostInventory.name, dt_params.sort_order)(), getattr(HostInventory.description, dt_params.sort_order)(), getattr(HostInventory.serial_number, dt_params.sort_order)(), getattr(HostInventory.hardware_revision, dt_params.sort_order)() ] host_inventory = query.order_by(columns[dt_params.column_order])\ .filter(and_(HostInventory.host_id == host.id), or_(*clauses))\ .slice(dt_params.start_length, dt_params.start_length + dt_params.display_length).all() for inventory in host_inventory: row = dict() row['location'] = inventory.location row['model_name'] = inventory.model_name row['name'] = inventory.name row['description'] = inventory.description row['serial_number'] = inventory.serial_number row['vid'] = inventory.hardware_revision rows.append(row) response = dict() response['draw'] = dt_params.draw response['recordsTotal'] = total_count response['recordsFiltered'] = filtered_count response['data'] = rows return jsonify(**response)
def api_get_last_successful_inventory_elapsed_time(hostname): db_session = DBSession() host = get_host(db_session, hostname) if host is None: abort(404) return jsonify(**{'data': [ {'last_successful_inventory_elapsed_time': get_last_successful_inventory_elapsed_time(host), 'status': host.inventory_job[0].status} ]})
def api_get_host_dashboard_software_inventory_history(hostname): rows = [] db_session = DBSession() host = get_host(db_session, hostname) if host is not None: inventory_jobs = db_session.query(InventoryJobHistory).filter(InventoryJobHistory.host_id == host.id). \ order_by(InventoryJobHistory.created_time.desc()) return jsonify(**get_inventory_job_json_dict(inventory_jobs)) return jsonify(**{'data': rows})
def api_remove_software_profile_for_host(hostname): if not can_create(current_user): abort(401) db_session = DBSession() host = get_host(db_session, hostname) if host: host.software_profile_id = None db_session.commit() return jsonify({'status': 'OK'}) else: return jsonify({'status': 'Failed'})
def api_get_inventory(hostname): rows = [] dt_params = DataTableParams(request) db_session = DBSession() host = get_host(db_session, hostname) if not host: abort(404) clauses = [] if len(dt_params.search_value): criteria = '%' + dt_params.search_value + '%' clauses.append(HostInventory.location.like(criteria)) clauses.append(HostInventory.model_name.like(criteria)) clauses.append(HostInventory.name.like(criteria)) clauses.append(HostInventory.description.like(criteria)) clauses.append(HostInventory.serial_number.like(criteria)) clauses.append(HostInventory.hardware_revision.like(criteria)) query = db_session.query(HostInventory)\ .join(Host, Host.id == HostInventory.host_id) total_count = query.filter(HostInventory.host_id == host.id).count() filtered_count = query.filter(and_(HostInventory.host_id == host.id), or_(*clauses)).count() columns = [getattr(HostInventory.location, dt_params.sort_order)(), getattr(HostInventory.model_name, dt_params.sort_order)(), getattr(HostInventory.name, dt_params.sort_order)(), getattr(HostInventory.description, dt_params.sort_order)(), getattr(HostInventory.serial_number, dt_params.sort_order)(), getattr(HostInventory.hardware_revision, dt_params.sort_order)()] host_inventory = query.order_by(columns[dt_params.column_order])\ .filter(and_(HostInventory.host_id == host.id), or_(*clauses))\ .slice(dt_params.start_length, dt_params.start_length + dt_params.display_length).all() for inventory in host_inventory: row = dict() row['location'] = inventory.location row['model_name'] = inventory.model_name row['name'] = inventory.name row['description'] = inventory.description row['serial_number'] = inventory.serial_number row['vid'] = inventory.hardware_revision rows.append(row) response = dict() response['draw'] = dt_params.draw response['recordsTotal'] = total_count response['recordsFiltered'] = filtered_count response['data'] = rows return jsonify(**response)
def get_inventory(hostname): if not can_retrieve_software(current_user): abort(401) db_session = DBSession() host = get_host(db_session, hostname) if host is not None: if not host.inventory_job[0].request_update: host.inventory_job[0].request_update = True db_session.commit() return jsonify({'status': 'OK'}) return jsonify({'status': 'Failed'})
def home(hostname): db_session = DBSession() host = get_host(db_session, hostname) if host is None: abort(404) return render_template('host/host_dashboard.html', host=host, form=get_host_schedule_install_form(request), system_option=SystemOption.get(db_session), package_states=[PackageState.ACTIVE_COMMITTED, PackageState.ACTIVE, PackageState.INACTIVE_COMMITTED, PackageState.INACTIVE])
def remove_host_enable_password(hostname): if not can_create(current_user): abort(401) db_session = DBSession() host = get_host(db_session, hostname) if host is not None: host.connection_param[0].enable_password = '' db_session.commit() return jsonify({'status': 'OK'}) else: return jsonify({'status': 'Failed'})
def api_get_host_dashboard_packages(hostname, package_state): db_session = DBSession() host = get_host(db_session, hostname) rows = [] if host is not None: # It is possible that package_state contains a commas delimited state list. # In this case, the union of those packages will be used. package_states = package_state.split(',') packages = [] for package_state in package_states: packages_list = db_session.query(Package).filter( and_(Package.host_id == host.id, Package.state == package_state)). order_by(Package.name).all() if len(packages_list) > 0: packages.extend(packages_list) has_module_packages = False for package in packages: if len(package.modules_package_state) > 0: has_module_packages = True break if has_module_packages: module_package_dict = {} # Format it from module, then packages for package in packages: package_name = package.name if package.location is None else package.location + ':' + package.name for modules_package_state in package.modules_package_state: module = modules_package_state.module_name if module in module_package_dict: module_package_dict[module].append(package_name) else: package_list = [] package_list.append(package_name) module_package_dict[module] = package_list sorted_dict = collections.OrderedDict(sorted(module_package_dict.items())) for module in sorted_dict: package_list = sorted_dict[module] rows.append({'package': module}) for package_name in package_list: rows.append({'package': (' ' * 7) + package_name}) else: for package in packages: rows.append({'package': package.name if package.location is None else package.location + ':' + package.name}) return jsonify(**{'data': rows})
def get_dependencies(): db_session = DBSession() hostnames = request.args.get('hosts', '', type=str).split(',') dependency = request.args.get('dependency', '', type=str) dependency_list = [] disqualified_count = 0 for hostname in hostnames: host = get_host(db_session, hostname) if host and host.connection_param[0] and (not host.connection_param[0].port_number): disqualified_count += 1 dependency_list.append('-2') continue if dependency: # Firstly, check if dependency action is scheduled or in progress, if so, add dependency last_unfinished_dependency_job = get_last_unfinished_install_action(db_session, dependency, get_host(db_session, hostname).id) if last_unfinished_dependency_job: dependency_list.append(last_unfinished_dependency_job.id) else: # Secondly, check if dependency action most recently completed or failed last_completed_or_failed_dependency_job = get_last_completed_or_failed_install_action(db_session, dependency, host.id) if last_completed_or_failed_dependency_job: if last_completed_or_failed_dependency_job.status == JobStatus.COMPLETED: dependency_list.append('-1') else: dependency_list.append(last_completed_or_failed_dependency_job.install_job_id) else: disqualified_count += 1 dependency_list.append('-2') else: dependency_list.append('-1') return jsonify(**{'data': [{'dependency_list': dependency_list, 'disqualified_count': disqualified_count}]})
def api_get_last_successful_inventory_elapsed_time(hostname): db_session = DBSession() host = get_host(db_session, hostname) if host is None: abort(404) return jsonify( **{ 'data': [{ 'last_successful_inventory_elapsed_time': get_last_successful_inventory_elapsed_time(host), 'status': host.inventory_job[0].status }] })
def get_software_package_upgrade_list(hostname, target_release): rows = [] db_session = DBSession() host = get_host(db_session, hostname) if host is None: abort(404) match_internal_name = True if request.args.get('match_internal_name') == 'true' else False host_packages = get_host_active_packages(hostname) target_packages = get_target_software_package_list(host.family, host.os_type, host_packages, target_release, match_internal_name) for package in target_packages: rows.append({'package': package}) return jsonify(**{'data': rows})
def api_get_host_dashboard_install_job_history(hostname): dt_params = DataTableParams(request) db_session = DBSession() host = get_host(db_session, hostname) if not host: abort(404) clauses = [] if len(dt_params.search_value): criteria = '%' + dt_params.search_value + '%' clauses.append(Host.hostname.like(criteria)) clauses.append(InstallJobHistory.install_action.like(criteria)) clauses.append(InstallJobHistory.scheduled_time.like(criteria)) clauses.append(InstallJobHistory.start_time.like(criteria)) clauses.append(InstallJobHistory.packages.like(criteria)) clauses.append(InstallJobHistory.status_time.like(criteria)) clauses.append(InstallJobHistory.created_by.like(criteria)) query = db_session.query(InstallJobHistory)\ .join(Host, Host.id == InstallJobHistory.host_id) total_count = query.filter(InstallJobHistory.host_id == host.id).count() filtered_count = query.filter(and_(InstallJobHistory.host_id == host.id), or_(*clauses)).count() columns = [ getattr(InstallJobHistory.install_action, dt_params.sort_order)(), getattr(InstallJobHistory.scheduled_time, dt_params.sort_order)(), getattr(InstallJobHistory.start_time, dt_params.sort_order)(), getattr(InstallJobHistory.packages, dt_params.sort_order)(), getattr(InstallJobHistory.status, dt_params.sort_order)(), getattr(InstallJobHistory.status_time, dt_params.sort_order)(), '', getattr(InstallJobHistory.created_by, dt_params.sort_order)() ] install_jobs = query.order_by(columns[dt_params.column_order])\ .filter(and_(InstallJobHistory.host_id == host.id), or_(*clauses))\ .slice(dt_params.start_length, dt_params.start_length + dt_params.display_length).all() response = dict() response['draw'] = dt_params.draw response['recordsTotal'] = total_count response['recordsFiltered'] = filtered_count response.update(get_install_job_json_dict(install_jobs)) return jsonify(**response)
def home(hostname): db_session = DBSession() host = get_host(db_session, hostname) if host is None: abort(404) return render_template('host/host_dashboard.html', host=host, form=get_host_schedule_install_form(request), system_option=SystemOption.get(db_session), package_states=[ PackageState.ACTIVE_COMMITTED, PackageState.ACTIVE, PackageState.INACTIVE_COMMITTED, PackageState.INACTIVE ])
def api_get_host_dashboard_install_job_history(hostname): dt_params = DataTableParams(request) db_session = DBSession() host = get_host(db_session, hostname) if not host: abort(404) clauses = [] if len(dt_params.search_value): criteria = '%' + dt_params.search_value + '%' clauses.append(Host.hostname.like(criteria)) clauses.append(InstallJobHistory.install_action.like(criteria)) clauses.append(InstallJobHistory.scheduled_time.like(criteria)) clauses.append(InstallJobHistory.start_time.like(criteria)) clauses.append(InstallJobHistory.packages.like(criteria)) clauses.append(InstallJobHistory.status_time.like(criteria)) clauses.append(InstallJobHistory.created_by.like(criteria)) query = db_session.query(InstallJobHistory)\ .join(Host, Host.id == InstallJobHistory.host_id) total_count = query.filter(InstallJobHistory.host_id == host.id).count() filtered_count = query.filter(and_(InstallJobHistory.host_id == host.id), or_(*clauses)).count() columns = [getattr(InstallJobHistory.install_action, dt_params.sort_order)(), getattr(InstallJobHistory.scheduled_time, dt_params.sort_order)(), getattr(InstallJobHistory.start_time, dt_params.sort_order)(), getattr(InstallJobHistory.packages, dt_params.sort_order)(), getattr(InstallJobHistory.status, dt_params.sort_order)(), getattr(InstallJobHistory.status_time, dt_params.sort_order)(), '', getattr(InstallJobHistory.created_by, dt_params.sort_order)()] install_jobs = query.order_by(columns[dt_params.column_order])\ .filter(and_(InstallJobHistory.host_id == host.id), or_(*clauses))\ .slice(dt_params.start_length, dt_params.start_length + dt_params.display_length).all() response = dict() response['draw'] = dt_params.draw response['recordsTotal'] = total_count response['recordsFiltered'] = filtered_count response.update(get_install_job_json_dict(install_jobs)) return jsonify(**response)
def host_create(): if not can_create(current_user): abort(401) form = HostForm(request.form) db_session = DBSession() fill_jump_hosts(db_session, form.jump_host.choices) fill_regions(db_session, form.region.choices) fill_software_profiles(db_session, form.software_profile.choices) if request.method == 'POST' and form.validate(): db_session = DBSession() try: host = get_host(db_session, form.hostname.data) if host is not None: return render_template('host/edit.html', form=form, duplicate_error=True) create_or_update_host( db_session=db_session, hostname=form.hostname.data, region_id=form.region.data, location=form.location.data, roles=form.roles.data, software_profile_id=form.software_profile.data, connection_type=form.connection_type.data, host_or_ip=form.host_or_ip.data, username=form.username.data, password=form.password.data, enable_password=form.enable_password.data, port_number=form.port_number.data, jump_host_id=form.jump_host.data, created_by=current_user.username) finally: db_session.rollback() return redirect(url_for('home')) return render_template('host/edit.html', form=form)
def get_software_package_upgrade_list(hostname, target_release): rows = [] db_session = DBSession() host = get_host(db_session, hostname) if host is None: abort(404) match_internal_name = True if request.args.get( 'match_internal_name') == 'true' else False host_packages = get_host_active_packages(hostname) target_packages = get_target_software_package_list(host.family, host.os_type, host_packages, target_release, match_internal_name) for package in target_packages: rows.append({'package': package}) return jsonify(**{'data': rows})
def api_get_host_dashboard_scheduled_install(hostname): """ Returns scheduled installs for a host in JSON format. """ db_session = DBSession() host = get_host(db_session, hostname) rows = [] if host is not None and len(host.install_job) > 0: for install_job in host.install_job: row = {} row['hostname'] = host.hostname row['install_job_id'] = install_job.id row['install_action'] = install_job.install_action row['scheduled_time'] = install_job.scheduled_time row['session_log'] = install_job.session_log row['status'] = install_job.status rows.append(row) return jsonify(**{'data': rows})
def api_create_install_jobs(): db_session = DBSession() hostname = request.form['hostname'] install_action = request.form.getlist('install_action[]') scheduled_time = request.form['scheduled_time_UTC'] software_packages = request.form['software_packages'].split() server_id = request.form['server'] server_directory = request.form['server_directory'] pending_downloads = request.form['pending_downloads'].split() custom_command_profile_ids = [ str(i) for i in request.form['custom_command_profile'].split() ] host = get_host(db_session, hostname) try: # The dependency on each install action is already indicated in the implicit ordering in the selector. # If the user selected Pre-Upgrade and Install Add, Install Add (successor) will # have Pre-Upgrade (predecessor) as the dependency. dependency = 0 for one_install_action in install_action: new_install_job = create_or_update_install_job( db_session=db_session, host_id=host.id, install_action=one_install_action, scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, pending_downloads=pending_downloads, custom_command_profile_ids=custom_command_profile_ids, dependency=dependency) dependency = new_install_job.id return jsonify({'status': 'OK'}) except Exception as e: logger.exception('api_create_install_job hit exception') return jsonify({'status': 'Failed Reason: ' + e.message})
def api_get_host_dashboard_cookie(hostname): db_session = DBSession() host = get_host(db_session, hostname) rows = [] if host is not None: software_profile = get_software_profile_by_id(db_session, host.software_profile_id) system_option = SystemOption.get(db_session) row = {} connection_param = host.connection_param[0] row['hostname'] = host.hostname row['region'] = host.region.name if host.region is not None else UNKNOWN row['location'] = host.location row['roles'] = host.roles row['platform'] = host.platform row['software_platform'] = host.software_platform row['software_version'] = host.software_version row['host_or_ip'] = connection_param.host_or_ip row['username'] = connection_param.username row['connection'] = connection_param.connection_type row['port_number'] = connection_param.port_number row['created_by'] = host.created_by row['software_profile_name'] = '' if software_profile is None else software_profile.name if connection_param.jump_host is not None: row['jump_host'] = connection_param.jump_host.hostname # Last inventory successful time inventory_job = host.inventory_job[0] row['last_successful_inventory_elapsed_time'] = get_last_successful_inventory_elapsed_time( host) row['last_successful_inventory_time'] = inventory_job.last_successful_time row['status'] = inventory_job.status row['can_schedule'] = system_option.can_schedule rows.append(row) return jsonify(**{'data': rows})
def home(request): """ Leads to Dashboard view. Args: request: HTTP request. Returns: displays all offers of a business """ login_form = AuthenticationForm(data=request.POST) # TODO: generalize to set of blocked emails. if login_form.is_valid(): business_user = simple_login_and_business_user(login_form, request) if request.POST.get('username') == '*****@*****.**': return redirect(common.get_host() + '/dashboard') else: return redirect('campañas/{}'.format(business_user.pk)) else: error_message = get_first_error_message(login_form) return render(request, cts.BUSINESS_LOGIN, {'error_message': error_message})
def api_get_supported_install_actions(hostname): db_session = DBSession() host = get_host(db_session, hostname) if host is None: abort(404) rows = [] if host.family == PlatformFamily.ASR900: rows.append({'install_options': [InstallAction.PRE_UPGRADE, InstallAction.INSTALL_ADD, InstallAction.INSTALL_ACTIVATE, InstallAction.POST_UPGRADE, InstallAction.ALL]}) rows.append({'cleanup_options': [InstallAction.INSTALL_REMOVE]}) else: rows.append({'install_options': [InstallAction.PRE_UPGRADE, InstallAction.INSTALL_ADD, InstallAction.INSTALL_ACTIVATE, InstallAction.POST_UPGRADE, InstallAction.INSTALL_COMMIT, InstallAction.ALL]}) rows.append({'cleanup_options': [InstallAction.INSTALL_REMOVE, InstallAction.INSTALL_REMOVE_ALL_INACTIVE, InstallAction.INSTALL_DEACTIVATE]}) rows.append({'other_options': [InstallAction.FPD_UPGRADE]}) return jsonify(**{'data': rows})
def api_get_host_dashboard_cookie(hostname): db_session = DBSession() host = get_host(db_session, hostname) rows = [] if host is not None: software_profile = get_software_profile_by_id(db_session, host.software_profile_id) system_option = SystemOption.get(db_session) row = {} connection_param = host.connection_param[0] row['hostname'] = host.hostname row['region'] = host.region.name if host.region is not None else UNKNOWN row['location'] = host.location row['roles'] = host.roles row['platform'] = host.platform row['software_platform'] = host.software_platform row['software_version'] = host.software_version row['host_or_ip'] = connection_param.host_or_ip row['username'] = connection_param.username row['connection'] = connection_param.connection_type row['port_number'] = connection_param.port_number row['created_by'] = host.created_by row['software_profile_name'] = '' if software_profile is None else software_profile.name if connection_param.jump_host is not None: row['jump_host'] = connection_param.jump_host.hostname # Last inventory successful time inventory_job = host.inventory_job[0] row['last_successful_inventory_elapsed_time'] = get_last_successful_inventory_elapsed_time(host) row['last_successful_inventory_time'] = inventory_job.last_successful_time row['status'] = inventory_job.status row['can_schedule'] = system_option.can_schedule rows.append(row) return jsonify(**{'data': rows})
def api_get_supported_install_actions(hostname): db_session = DBSession() host = get_host(db_session, hostname) if host is None: abort(404) rows = [] if host.family == PlatformFamily.ASR900: rows.append({ 'install_options': [ InstallAction.PRE_UPGRADE, InstallAction.INSTALL_ADD, InstallAction.INSTALL_ACTIVATE, InstallAction.POST_UPGRADE, InstallAction.ALL ] }) rows.append({'cleanup_options': [InstallAction.INSTALL_REMOVE]}) else: rows.append({ 'install_options': [ InstallAction.PRE_UPGRADE, InstallAction.INSTALL_ADD, InstallAction.INSTALL_ACTIVATE, InstallAction.POST_UPGRADE, InstallAction.INSTALL_COMMIT, InstallAction.ALL ] }) rows.append({ 'cleanup_options': [ InstallAction.INSTALL_REMOVE, InstallAction.INSTALL_REMOVE_ALL_INACTIVE, InstallAction.INSTALL_DEACTIVATE ] }) rows.append({'other_options': [InstallAction.FPD_UPGRADE]}) return jsonify(**{'data': rows})
def api_get_install_history(hostname): if not can_retrieve_software(current_user): abort(401) rows = [] db_session = DBSession() host = get_host(db_session, hostname) if host is not None: install_jobs = db_session.query(InstallJobHistory). \ filter((InstallJobHistory.host_id == host.id), and_(InstallJobHistory.install_action == InstallAction.INSTALL_ADD, InstallJobHistory.status == JobStatus.COMPLETED)).\ order_by(InstallJobHistory.status_time.desc()) for install_job in install_jobs: if not is_empty(install_job.packages): row = {} row['packages'] = install_job.packages row['status_time'] = install_job.status_time row['created_by'] = install_job.created_by rows.append(row) return jsonify(**{'data': rows})
def api_get_host_packages_by_states(hostname): """ Returns the software packages that satisfy the requested package states (e.g. 'active,committed') """ package_state = request.args.get('package_state') db_session = DBSession() host = get_host(db_session, hostname) rows = [] if host is not None: # It is possible that package_state contains a commas delimited state list. # In this case, the union of those packages will be used. package_states = package_state.split(',') packages = [] for package_state in package_states: packages_list = db_session.query(Package).filter( and_(Package.host_id == host.id, Package.state == package_state)). order_by(Package.name).all() if len(packages_list) > 0: packages.extend(packages_list) for package in packages: rows.append({'package': package.name if package.location is None else package.location + ':' + package.name}) return jsonify(**{'data': rows})
def handle_schedule_install_form(request, db_session, hostname, install_job=None): host = get_host(db_session, hostname) if host is None: abort(404) return_url = get_return_url(request, 'host_dashboard.home') schedule_form = ScheduleMigrationForm(request.form) # Fills the selections fill_servers(schedule_form.server_dialog_server.choices, host.region.servers, include_local=False) fill_custom_command_profiles(db_session, schedule_form.custom_command_profile.choices) fill_hardware_audit_version(schedule_form.hardware_audit_version.choices) if request.method == 'POST': if install_job is not None: # In Edit mode, the install_action UI on HostScheduleForm is disabled (not allowed to change). # Thus, there will be no value returned by form.install_action.data. So, re-use the existing ones. install_action = [install_job.install_action] else: install_action = schedule_form.install_action.data scheduled_time = schedule_form.scheduled_time_UTC.data software_packages = schedule_form.hidden_software_packages.data.split() server_id = schedule_form.hidden_server.data server_directory = schedule_form.hidden_server_directory.data custom_command_profile_ids = [ str(i) for i in schedule_form.custom_command_profile.data ] if InstallAction.MIGRATION_AUDIT in install_action: host.context[0].data['hardware_audit_version'] = \ schedule_form.hidden_hardware_audit_version.data if InstallAction.PRE_MIGRATE in install_action: host.context[0].data[ 'config_filename'] = schedule_form.hidden_config_filename.data host.context[0].data[ 'override_hw_req'] = schedule_form.hidden_override_hw_req.data # install_action is a list object which can only contain one install action # at this editing time, accept the selected dependency if any dependency = int(schedule_form.hidden_dependency.data) create_or_update_install_job( db_session=db_session, host_id=host.id, install_action=install_action[0], scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, custom_command_profile_ids=custom_command_profile_ids, dependency=dependency, install_job=install_job) return redirect(url_for(return_url, hostname=hostname)) elif request.method == 'GET': # Initialize the hidden fields schedule_form.hidden_server.data = -1 schedule_form.hidden_server_name.data = '' schedule_form.hidden_server_directory.data = '' schedule_form.hidden_pending_downloads.data = '' schedule_form.hidden_edit.data = install_job is not None schedule_form.hidden_region.data = str(host.region.name) fill_default_region(schedule_form.region.choices, host.region) schedule_form.hidden_hosts.data = hostname schedule_form.hidden_dependency.data = '' # In Edit mode if install_job is not None: schedule_form.install_action.data = install_job.install_action if install_job.custom_command_profile_ids: ids = [ str(id) for id in install_job.custom_command_profile_ids.split(',') ] schedule_form.custom_command_profile.data = ids schedule_form.hidden_override_hw_req.data = host.context[ 0].data.get('override_hw_req') schedule_form.hidden_config_filename.data = host.context[ 0].data.get('config_filename') schedule_form.hidden_hardware_audit_version.data = host.context[ 0].data.get('hardware_audit_version') if install_job.server_id is not None: schedule_form.hidden_server.data = install_job.server_id server = get_server_by_id(db_session, install_job.server_id) if server is not None: schedule_form.hidden_server_name.data = server.hostname schedule_form.hidden_server_directory.data = '' if install_job.server_directory is None \ else install_job.server_directory schedule_form.hidden_pending_downloads.data = '' if install_job.pending_downloads is None \ else install_job.pending_downloads # Form a line separated list for the textarea if install_job.packages is not None: schedule_form.hidden_software_packages.data = install_job.packages if install_job.dependency is not None: schedule_form.hidden_dependency.data = str( install_job.dependency) else: schedule_form.hidden_dependency.data = '-1' if install_job.scheduled_time is not None: schedule_form.scheduled_time_UTC.data = get_datetime_string( install_job.scheduled_time) return render_template('asr9k_64_migrate/migration.html', schedule_form=schedule_form, system_option=SystemOption.get(db_session), host=host, server_time=datetime.datetime.utcnow(), install_job=install_job, return_url=return_url, install_action=get_install_migrations_dict(), input_filename="", err_msg="")
def migration(): # only operator and above can schedule migration if not can_install(current_user): render_template('user/not_authorized.html', user=current_user) # temp_user_dir = create_temp_user_directory(current_user.username) # config_file_path = os.path.normpath(os.path.join(temp_user_dir, "config_conversion")) # create_directory(config_file_path) # current_app.config['UPLOAD_FOLDER'] = config_file_path # print "current_app.config.get('UPLOAD_FOLDER') = " + current_app.config.get('UPLOAD_FOLDER') db_session = DBSession() return_url = get_return_url(request, 'install_dashboard.home') schedule_form = init_schedule_form(db_session, request, get=request.method == 'GET') config_form = init_config_form(db_session, request, get=request.method == 'GET') if request.method == 'POST': print(str(config_form.data)) if config_form.hidden_submit_config_form.data == "True": return convert_config(db_session, request, 'asr9k_64_migrate/migration.html', schedule_form) # Retrieves from the multi-select box hostnames = schedule_form.hidden_hosts.data.split(',') install_action = schedule_form.install_action.data if hostnames is not None: print(str(schedule_form.data)) print(str(hostnames)) dependency_list = schedule_form.hidden_dependency.data.split(',') index = 0 for hostname in hostnames: host = get_host(db_session, hostname) if host is not None: db_session = DBSession() scheduled_time = schedule_form.scheduled_time_UTC.data software_packages = schedule_form.hidden_software_packages.data.split() server_id = schedule_form.hidden_server.data server_directory = schedule_form.hidden_server_directory.data custom_command_profile_ids = [str(i) for i in schedule_form.custom_command_profile.data] if InstallAction.MIGRATION_AUDIT in install_action: host.context[0].data['hardware_audit_version'] = \ schedule_form.hidden_hardware_audit_version.data if InstallAction.PRE_MIGRATE in install_action: host.context[0].data['config_filename'] = schedule_form.hidden_config_filename.data host.context[0].data['override_hw_req'] = schedule_form.hidden_override_hw_req.data # If the dependency is a previous job id, it's non-negative int string. if int(dependency_list[index]) >= 0: dependency = dependency_list[index] # In this case, the dependency is '-1', which means no dependency for the first install action else: dependency = 0 # The dependency for the first install action depends on dependency_list[index]. # The dependency for each install action following first is indicated by the implicit # ordering in the selector. If the user selected Pre-Migrate and Migrate, # Migrate (successor) will have Pre-Migrate (predecessor) as the dependency. for i in xrange(0, len(install_action)): new_install_job = create_or_update_install_job(db_session=db_session, host_id=host.id, install_action=install_action[i], scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, custom_command_profile_ids=custom_command_profile_ids, dependency=dependency) print("dependency for install_action = {} is {}".format(install_action[i], str(dependency))) dependency = new_install_job.id index += 1 return redirect(url_for(return_url)) else: return render_template('asr9k_64_migrate/migration.html', schedule_form=schedule_form, install_action=get_install_migrations_dict(), server_time=datetime.datetime.utcnow(), system_option=SystemOption.get(db_session), config_form=config_form, input_filename="", err_msg="", )
def batch_schedule_install(): """ For batch scheduled installation. """ if not can_install(current_user): abort(401) db_session = DBSession() form = ScheduleInstallForm(request.form) # Fills the selections fill_regions(db_session, form.region.choices) fill_dependencies(form.dependency.choices) fill_custom_command_profiles(db_session, form.custom_command_profile.choices) return_url = get_return_url(request, 'home') if request.method == 'POST': # and form.validate(): """ f = request.form for key in f.keys(): for value in f.getlist(key): print(key,":",value) """ # Retrieves from the multi-select box hostnames = form.hidden_selected_hosts.data.split(',') install_action = form.install_action.data custom_command_profile_ids = [str(i) for i in form.custom_command_profile.data] if hostnames is not None: for hostname in hostnames: host = get_host(db_session, hostname) if host is not None: db_session = DBSession() scheduled_time = form.scheduled_time_UTC.data software_packages = form.software_packages.data.split() server_id = form.hidden_server.data server_directory = form.hidden_server_directory.data pending_downloads = form.hidden_pending_downloads.data.split() # If only one install_action, accept the selected dependency if any dependency = 0 if len(install_action) == 1: # No dependency when it is 0 (a digit) if not form.dependency.data.isdigit(): prerequisite_install_job = get_last_install_action(db_session, form.dependency.data, host.id) if prerequisite_install_job is not None: dependency = prerequisite_install_job.id create_or_update_install_job(db_session=db_session, host_id=host.id, install_action=install_action[0], custom_command_profile_ids=custom_command_profile_ids, scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, pending_downloads=pending_downloads, dependency=dependency, created_by=current_user.username) else: # The dependency on each install action is already indicated in the implicit ordering # in the selector. If the user selected Pre-Upgrade and Install Add, Install Add (successor) # will have Pre-Upgrade (predecessor) as the dependency. dependency = 0 for one_install_action in install_action: new_install_job = create_or_update_install_job(db_session=db_session, host_id=host.id, install_action=one_install_action, scheduled_time=scheduled_time, custom_command_profile_ids=custom_command_profile_ids, software_packages=software_packages, server_id=server_id, server_directory=server_directory, pending_downloads=pending_downloads, dependency=dependency, created_by=current_user.username) dependency = new_install_job.id return redirect(url_for(return_url)) else: # Initialize the hidden fields form.hidden_server.data = -1 form.hidden_server_name.data = '' form.hidden_server_directory.data = '' form.hidden_pending_downloads.data = '' return render_template('schedule_install.html', form=form, system_option=SystemOption.get(db_session), server_time=datetime.datetime.utcnow(), return_url=return_url)
def handle_schedule_install_form(request, db_session, hostname, install_job=None): host = get_host(db_session, hostname) if host is None: abort(404) return_url = get_return_url(request, 'host_dashboard.home') form = HostScheduleInstallForm(request.form) # Retrieves all the install jobs for this host. This will allow # the user to select which install job this install job can depend on. install_jobs = db_session.query(InstallJob).filter( InstallJob.host_id == host.id).order_by(InstallJob.scheduled_time.asc()).all() region_servers = host.region.servers # Returns all server repositories if the region does not have any server repository designated. if is_empty(region_servers): region_servers = get_server_list(db_session) # Fills the selections fill_servers(form.server_dialog_server.choices, region_servers) fill_servers(form.server_modal_dialog_server.choices, region_servers) fill_servers(form.cisco_dialog_server.choices, region_servers, False) fill_dependency_from_host_install_jobs(form.dependency.choices, install_jobs, (-1 if install_job is None else install_job.id)) fill_custom_command_profiles(db_session, form.custom_command_profile.choices) if request.method == 'POST': if install_job is not None: # In Edit mode, the install_action UI on HostScheduleForm is disabled (not allow to change). # Thus, there will be no value returned by form.install_action.data. So, re-use the existing ones. install_action = [install_job.install_action] else: install_action = form.install_action.data scheduled_time = form.scheduled_time_UTC.data software_packages = form.software_packages.data.split() server_id = form.hidden_server.data server_directory = form.hidden_server_directory.data pending_downloads = form.hidden_pending_downloads.data.split() custom_command_profile_ids = [str(i) for i in form.custom_command_profile.data] # install_action is a list object which may contain multiple install actions. # If only one install_action, accept the selected dependency if any if len(install_action) == 1: dependency = int(form.dependency.data) create_or_update_install_job(db_session=db_session, host_id=host.id, install_action=install_action[0], scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, pending_downloads=pending_downloads, custom_command_profile_ids=custom_command_profile_ids, dependency=dependency, created_by=current_user.username, install_job=install_job) else: # The dependency on each install action is already indicated in the implicit ordering in the selector. # If the user selected Pre-Upgrade and Install Add, Install Add (successor) will # have Pre-Upgrade (predecessor) as the dependency. dependency = 0 for one_install_action in install_action: new_install_job = create_or_update_install_job(db_session=db_session, host_id=host.id, install_action=one_install_action, scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, pending_downloads=pending_downloads, custom_command_profile_ids=custom_command_profile_ids, dependency=dependency, created_by=current_user.username, install_job=install_job) dependency = new_install_job.id return redirect(url_for(return_url, hostname=hostname)) elif request.method == 'GET': # Initialize the hidden fields form.hidden_server.data = -1 form.hidden_selected_hosts.data = '' form.hidden_server_name.data = '' form.hidden_server_directory.data = '' form.hidden_pending_downloads.data = '' form.hidden_edit.data = install_job is not None # In Edit mode if install_job is not None: form.install_action.data = install_job.install_action if install_job.server_id is not None: form.hidden_server.data = install_job.server_id server = get_server_by_id(db_session, install_job.server_id) if server is not None: form.hidden_server_name.data = server.hostname form.hidden_server_directory.data = '' if install_job.server_directory is None else install_job.server_directory form.hidden_pending_downloads.data = '' if install_job.pending_downloads is None else install_job.pending_downloads # Form a line separated list for the textarea if install_job.packages is not None: form.software_packages.data = '\n'.join(install_job.packages.split(',')) form.dependency.data = str(install_job.dependency) if install_job.scheduled_time is not None: form.scheduled_time_UTC.data = get_datetime_string(install_job.scheduled_time) if install_job.custom_command_profile_ids: ids = [int(id) for id in install_job.custom_command_profile_ids.split(',')] form.custom_command_profile.data = ids return render_template('host/schedule_install.html', form=form, system_option=SystemOption.get(db_session), host=host, server_time=datetime.datetime.utcnow(), install_job=install_job, return_url=return_url)
def api_import_hosts(): importable_header = [ HEADER_FIELD_HOSTNAME, HEADER_FIELD_REGION, HEADER_FIELD_ROLES, HEADER_FIELD_IP, HEADER_FIELD_USERNAME, HEADER_FIELD_PASSWORD, HEADER_FIELD_CONNECTION, HEADER_FIELD_PORT ] region_id = request.form['region'] data_list = request.form['data_list'] db_session = DBSession() selected_region = get_region_by_id(db_session, region_id) if selected_region is None: return jsonify( {'status': 'Region is no longer exists in the database.'}) # Check mandatory data fields error = [] reader = csv.reader(data_list.splitlines(), delimiter=',') header_row = next(reader) if HEADER_FIELD_HOSTNAME not in header_row: error.append('"hostname" is missing in the header.') if HEADER_FIELD_IP not in header_row: error.append('"ip" is missing in the header.') if HEADER_FIELD_CONNECTION not in header_row: error.append('"connection" is missing in the header.') for header_field in header_row: if header_field not in importable_header: error.append('"' + header_field + '" is not a correct header field.') if error: return jsonify({'status': ','.join(error)}) # Check if each row has the same number of data fields as the header error = [] data_list = list(reader) row = 2 COLUMN_CONNECTION = get_column_number(header_row, HEADER_FIELD_CONNECTION) COLUMN_REGION = get_column_number(header_row, HEADER_FIELD_REGION) for row_data in data_list: if len(row_data) > 0: if len(row_data) != len(header_row): error.append('line %d has wrong number of data fields.' % row) else: if COLUMN_CONNECTION >= 0: # Validate the connection type data_field = row_data[COLUMN_CONNECTION] if data_field != ConnectionType.TELNET and data_field != ConnectionType.SSH: error.append( 'line %d has a wrong connection type (should either be "telnet" or "ssh").' % row) if COLUMN_REGION >= 0: # Create a region if necessary data_field = get_acceptable_string(row_data[COLUMN_REGION]) region = get_region(db_session, data_field) if region is None and data_field: try: db_session.add( Region(name=data_field, created_by=current_user.username)) db_session.commit() except Exception: db_session.rollback() error.append('Unable to create region %s.' % data_field) row += 1 if error: return jsonify({'status': ','.join(error)}) # Import the data error = [] im_regions = {} for data in data_list: if len(data) == 0: continue db_host = None im_host = Host() im_host.region_id = selected_region.id im_host.created_by = current_user.username im_host.inventory_job.append(InventoryJob()) im_host.context.append(HostContext()) im_host.connection_param.append(ConnectionParam()) im_host.connection_param[0].username = '' im_host.connection_param[0].password = '' im_host.connection_param[0].port_number = '' for column in range(len(header_row)): header_field = header_row[column] data_field = data[column].strip() if header_field == HEADER_FIELD_HOSTNAME: hostname = get_acceptable_string(data_field) db_host = get_host(db_session, hostname) im_host.hostname = hostname elif header_field == HEADER_FIELD_REGION: region_name = get_acceptable_string(data_field) if region_name in im_regions: im_host.region_id = im_regions[region_name] else: region = get_region(db_session, region_name) if region is not None: im_host.region_id = region.id # Saved for later lookup im_regions[region_name] = region.id elif header_field == HEADER_FIELD_ROLES: im_host.roles = remove_extra_spaces(data_field) elif header_field == HEADER_FIELD_IP: im_host.connection_param[0].host_or_ip = remove_extra_spaces( data_field) elif header_field == HEADER_FIELD_USERNAME: username = get_acceptable_string(data_field) im_host.connection_param[0].username = username elif header_field == HEADER_FIELD_PASSWORD: im_host.connection_param[0].password = data_field elif header_field == HEADER_FIELD_CONNECTION: im_host.connection_param[0].connection_type = data_field elif header_field == HEADER_FIELD_PORT: im_host.connection_param[0].port_number = remove_extra_spaces( data_field) # Import host already exists in the database, just update it if db_host is not None: db_host.created_by = im_host.created_by db_host.region_id = im_host.region_id if HEADER_FIELD_ROLES in header_row: db_host.roles = im_host.roles if HEADER_FIELD_IP in header_row: db_host.connection_param[ 0].host_or_ip = im_host.connection_param[0].host_or_ip if HEADER_FIELD_USERNAME in header_row: db_host.connection_param[ 0].username = im_host.connection_param[0].username if HEADER_FIELD_PASSWORD in header_row: db_host.connection_param[ 0].password = im_host.connection_param[0].password if HEADER_FIELD_CONNECTION in header_row: db_host.connection_param[ 0].connection_type = im_host.connection_param[ 0].connection_type if HEADER_FIELD_PORT in header_row: db_host.connection_param[ 0].port_number = im_host.connection_param[0].port_number else: # Add the import host db_session.add(im_host) if error: return jsonify({'status': error}) else: db_session.commit() return jsonify({'status': 'OK'})
def run_conformance_report(db_session, software_profile, match_criteria, hostnames): """ software_profile: SoftwareProfile instance hostnames: a list of hostnames """ host_not_in_conformance = 0 host_out_dated_inventory = 0 software_profile_packages = software_profile.packages.split(',') conformance_report = ConformanceReport( software_profile=software_profile.name, software_profile_packages=','.join(sorted(software_profile_packages)), match_criteria=match_criteria, hostnames=','.join(hostnames), user_id=current_user.id, created_by=current_user.username) software_profile_package_dict = fixup_software_profile_packages(software_profile_packages) for hostname in hostnames: host = get_host(db_session, hostname) if host: inventory_job = host.inventory_job[0] comments = '' if inventory_job is not None and inventory_job.last_successful_time is not None: comments = '(' + get_last_successful_inventory_elapsed_time(host) + ')' if inventory_job.status != JobStatus.COMPLETED: comments += ' *' host_out_dated_inventory += 1 host_packages = [] if match_criteria == 'inactive': host_packages = get_host_inactive_packages(hostname) elif match_criteria == 'active': host_packages = get_host_active_packages(hostname) missing_packages = get_missing_packages(host_packages, software_profile_package_dict) if missing_packages: host_not_in_conformance += 1 conformed = False if len(host_packages) > 0 and len(missing_packages) == 0: conformed = True conformance_report_entry = ConformanceReportEntry( hostname=hostname, software_platform=UNKNOWN if host.software_platform is None else host.software_platform, software_version=UNKNOWN if host.software_version is None else host.software_version, conformed=HostConformanceStatus.CONFORM if conformed else HostConformanceStatus.NON_CONFORM, comments=comments, host_packages=','.join(sorted(get_match_result(host_packages, software_profile_package_dict.values()))), missing_packages=','.join(sorted(missing_packages))) else: # Flag host not found condition host_out_dated_inventory += 1 host_not_in_conformance += 1 conformance_report_entry = ConformanceReportEntry( hostname=hostname, software_platform='MISSING', software_version='MISSING', host_packages='MISSING', missing_packages='MISSING') conformance_report.entries.append(conformance_report_entry) conformance_report.host_not_in_conformance = host_not_in_conformance conformance_report.host_out_dated_inventory = host_out_dated_inventory db_session.add(conformance_report) db_session.commit() purge_old_conformance_reports(db_session) return jsonify({'status': 'OK'})
def api_get_install_request(request): """ GET: http://localhost:5000/api/v1/install http://localhost:5000/api/v1/install?id=1 http://localhost:5000/api/v1/install?hostname=R1 http://localhost:5000/api/v1/install?hostname=r1&install_action=Add http://localhost:5000/api/v1/install?hostname=R1&status="failed" """ validate_url_parameters(request, [KEY_ID, KEY_HOSTNAME, KEY_INSTALL_ACTION, KEY_STATUS, KEY_SCHEDULED_TIME, KEY_UTC_OFFSET]) clauses = [] db_session = DBSession id = request.args.get(KEY_ID) hostname = request.args.get(KEY_HOSTNAME) install_action = request.args.get(KEY_INSTALL_ACTION) status = request.args.get(KEY_STATUS) scheduled_time = request.args.get(KEY_SCHEDULED_TIME) utc_offset = request.args.get(KEY_UTC_OFFSET) if utc_offset and '-' not in utc_offset and '+' not in utc_offset: utc_offset = "+" + utc_offset.strip() if id: # Use all() instead of first() so the return is a list type. install_jobs = db_session.query(InstallJob).filter(InstallJob.id == id).all() if not install_jobs: # It is possible that this query may result in multiple rows # 1) the install job id may be re-used by other hosts. # 2) if the install job was re-submitted. install_jobs = db_session.query(InstallJobHistory).filter(InstallJobHistory.install_job_id == id).all() if not install_jobs: raise ValueError("Install id '{}' does not exist in the database.".format(id)) else: table_to_query = InstallJob if status: if status not in [JobStatus.SCHEDULED, JobStatus.IN_PROGRESS, JobStatus.FAILED, JobStatus.COMPLETED]: raise ValueError("'{}' is an invalid job status.".format(status)) if status == JobStatus.SCHEDULED: clauses.append(InstallJob.status == None) elif status == JobStatus.IN_PROGRESS: clauses.append(and_(InstallJob.status != None, InstallJob.status != JobStatus.FAILED)) elif status in [JobStatus.COMPLETED, JobStatus.FAILED]: table_to_query = InstallJobHistory clauses.append(InstallJobHistory.status == status) if hostname: host = get_host(db_session, hostname) if host: if table_to_query == InstallJob: clauses.append(InstallJob.host_id == host.id) else: clauses.append(InstallJobHistory.host_id == host.id) else: raise ValueError("Host '{}' does not exist in the database.".format(hostname)) if install_action: if install_action not in [InstallAction.PRE_UPGRADE, InstallAction.INSTALL_ADD, InstallAction.INSTALL_ACTIVATE, InstallAction.POST_UPGRADE, InstallAction.INSTALL_COMMIT, InstallAction.INSTALL_REMOVE, InstallAction.INSTALL_DEACTIVATE]: raise ValueError("'{}' is an invalid install action.".format(install_action)) if table_to_query == InstallJob: clauses.append(InstallJob.install_action == install_action) else: clauses.append(InstallJobHistory.install_action == install_action) if scheduled_time: if not utc_offset: raise ValueError("utc_offset must be specified if scheduled_time is specified.") elif not verify_utc_offset(utc_offset): raise ValueError("Invalid utc_offset: Must be in '<+|->dd:dd' format and be between -12:00 and +14:00.") try: time = datetime.strptime(scheduled_time, "%m-%d-%Y %I:%M %p") time_utc = get_utc_time(time, utc_offset) if table_to_query == InstallJob: clauses.append(InstallJob.scheduled_time >= time_utc) else: clauses.append(InstallJobHistory.scheduled_time >= time_utc) except: raise ValueError("Invalid scheduled_time: '{}' must be in 'mm-dd-yyyy hh:mm AM|PM' format.".format(time)) install_jobs = get_install_jobs(table_to_query, db_session, clauses) rows = [] error_found = False for install_job in install_jobs: row = [] try: row = get_install_job_info(db_session, install_job, utc_offset) 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 handle_schedule_install_form(request, db_session, hostname, install_job=None): host = get_host(db_session, hostname) if host is None: abort(404) return_url = get_return_url(request, 'host_dashboard.home') schedule_form = ScheduleMigrationForm(request.form) # Fills the selections fill_servers(schedule_form.server_dialog_server.choices, host.region.servers, include_local=False) fill_custom_command_profiles(db_session, schedule_form.custom_command_profile.choices) fill_hardware_audit_version(schedule_form.hardware_audit_version.choices) if request.method == 'POST': if install_job is not None: # In Edit mode, the install_action UI on HostScheduleForm is disabled (not allowed to change). # Thus, there will be no value returned by form.install_action.data. So, re-use the existing ones. install_action = [ install_job.install_action ] else: install_action = schedule_form.install_action.data scheduled_time = schedule_form.scheduled_time_UTC.data software_packages = schedule_form.hidden_software_packages.data.split() server_id = schedule_form.hidden_server.data server_directory = schedule_form.hidden_server_directory.data custom_command_profile_ids = [str(i) for i in schedule_form.custom_command_profile.data] if InstallAction.MIGRATION_AUDIT in install_action: host.context[0].data['hardware_audit_version'] = \ schedule_form.hidden_hardware_audit_version.data if InstallAction.PRE_MIGRATE in install_action: host.context[0].data['config_filename'] = schedule_form.hidden_config_filename.data host.context[0].data['override_hw_req'] = schedule_form.hidden_override_hw_req.data # install_action is a list object which can only contain one install action # at this editing time, accept the selected dependency if any dependency = int(schedule_form.hidden_dependency.data) create_or_update_install_job(db_session=db_session, host_id=host.id, install_action=install_action[0], scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, custom_command_profile_ids=custom_command_profile_ids, dependency=dependency, install_job=install_job) return redirect(url_for(return_url, hostname=hostname)) elif request.method == 'GET': # Initialize the hidden fields schedule_form.hidden_server.data = -1 schedule_form.hidden_server_name.data = '' schedule_form.hidden_server_directory.data = '' schedule_form.hidden_pending_downloads.data = '' schedule_form.hidden_edit.data = install_job is not None schedule_form.hidden_region.data = str(host.region.name) fill_default_region(schedule_form.region.choices, host.region) schedule_form.hidden_hosts.data = hostname schedule_form.hidden_dependency.data = '' # In Edit mode if install_job is not None: schedule_form.install_action.data = install_job.install_action if install_job.custom_command_profile_ids: ids = [str(id) for id in install_job.custom_command_profile_ids.split(',')] schedule_form.custom_command_profile.data = ids schedule_form.hidden_override_hw_req.data = host.context[0].data.get('override_hw_req') schedule_form.hidden_config_filename.data = host.context[0].data.get('config_filename') schedule_form.hidden_hardware_audit_version.data = host.context[0].data.get('hardware_audit_version') if install_job.server_id is not None: schedule_form.hidden_server.data = install_job.server_id server = get_server_by_id(db_session, install_job.server_id) if server is not None: schedule_form.hidden_server_name.data = server.hostname schedule_form.hidden_server_directory.data = '' if install_job.server_directory is None \ else install_job.server_directory schedule_form.hidden_pending_downloads.data = '' if install_job.pending_downloads is None \ else install_job.pending_downloads # Form a line separated list for the textarea if install_job.packages is not None: schedule_form.hidden_software_packages.data = install_job.packages if install_job.dependency is not None: schedule_form.hidden_dependency.data = str(install_job.dependency) else: schedule_form.hidden_dependency.data = '-1' if install_job.scheduled_time is not None: schedule_form.scheduled_time_UTC.data = get_datetime_string(install_job.scheduled_time) return render_template('asr9k_64_migrate/migration.html', schedule_form=schedule_form, system_option=SystemOption.get(db_session), host=host, server_time=datetime.datetime.utcnow(), install_job=install_job, return_url=return_url, install_action=get_install_migrations_dict(), input_filename="", err_msg="")
def api_import_hosts(): importable_header = [HEADER_FIELD_HOSTNAME, HEADER_FIELD_REGION, HEADER_FIELD_ROLES, HEADER_FIELD_IP, HEADER_FIELD_USERNAME, HEADER_FIELD_PASSWORD, HEADER_FIELD_CONNECTION, HEADER_FIELD_PORT] region_id = request.form['region'] data_list = request.form['data_list'] db_session = DBSession() selected_region = get_region_by_id(db_session, region_id) if selected_region is None: return jsonify({'status': 'Region is no longer exists in the database.'}) # Check mandatory data fields error = [] reader = csv.reader(data_list.splitlines(), delimiter=',') header_row = next(reader) if HEADER_FIELD_HOSTNAME not in header_row: error.append('"hostname" is missing in the header.') if HEADER_FIELD_IP not in header_row: error.append('"ip" is missing in the header.') if HEADER_FIELD_CONNECTION not in header_row: error.append('"connection" is missing in the header.') for header_field in header_row: if header_field not in importable_header: error.append('"' + header_field + '" is not a correct header field.') if error: return jsonify({'status': ','.join(error)}) # Check if each row has the same number of data fields as the header error = [] data_list = list(reader) row = 2 COLUMN_CONNECTION = get_column_number(header_row, HEADER_FIELD_CONNECTION) COLUMN_REGION = get_column_number(header_row, HEADER_FIELD_REGION) for row_data in data_list: if len(row_data) > 0: if len(row_data) != len(header_row): error.append('line %d has wrong number of data fields.' % row) else: if COLUMN_CONNECTION >= 0: # Validate the connection type data_field = row_data[COLUMN_CONNECTION] if data_field != ConnectionType.TELNET and data_field != ConnectionType.SSH: error.append('line %d has a wrong connection type (should either be "telnet" or "ssh").' % row) if COLUMN_REGION >= 0: # Create a region if necessary data_field = get_acceptable_string(row_data[COLUMN_REGION]) region = get_region(db_session, data_field) if region is None and data_field: try: db_session.add(Region(name=data_field, created_by=current_user.username)) db_session.commit() except Exception: db_session.rollback() error.append('Unable to create region %s.' % data_field) row += 1 if error: return jsonify({'status': ','.join(error)}) # Import the data error = [] im_regions = {} for data in data_list: if len(data) == 0: continue db_host = None im_host = Host() im_host.region_id = selected_region.id im_host.created_by = current_user.username im_host.inventory_job.append(InventoryJob()) im_host.context.append(HostContext()) im_host.connection_param.append(ConnectionParam()) im_host.connection_param[0].username = '' im_host.connection_param[0].password = '' im_host.connection_param[0].port_number = '' for column in range(len(header_row)): header_field = header_row[column] data_field = data[column].strip() if header_field == HEADER_FIELD_HOSTNAME: hostname = get_acceptable_string(data_field) db_host = get_host(db_session, hostname) im_host.hostname = hostname elif header_field == HEADER_FIELD_REGION: region_name = get_acceptable_string(data_field) if region_name in im_regions: im_host.region_id = im_regions[region_name] else: region = get_region(db_session, region_name) if region is not None: im_host.region_id = region.id # Saved for later lookup im_regions[region_name] = region.id elif header_field == HEADER_FIELD_ROLES: im_host.roles = remove_extra_spaces(data_field) elif header_field == HEADER_FIELD_IP: im_host.connection_param[0].host_or_ip = remove_extra_spaces(data_field) elif header_field == HEADER_FIELD_USERNAME: username = get_acceptable_string(data_field) im_host.connection_param[0].username = username elif header_field == HEADER_FIELD_PASSWORD: im_host.connection_param[0].password = data_field elif header_field == HEADER_FIELD_CONNECTION: im_host.connection_param[0].connection_type = data_field elif header_field == HEADER_FIELD_PORT: im_host.connection_param[0].port_number = remove_extra_spaces(data_field) # Import host already exists in the database, just update it if db_host is not None: db_host.created_by = im_host.created_by db_host.region_id = im_host.region_id if HEADER_FIELD_ROLES in header_row: db_host.roles = im_host.roles if HEADER_FIELD_IP in header_row: db_host.connection_param[0].host_or_ip = im_host.connection_param[0].host_or_ip if HEADER_FIELD_USERNAME in header_row: db_host.connection_param[0].username = im_host.connection_param[0].username if HEADER_FIELD_PASSWORD in header_row: db_host.connection_param[0].password = im_host.connection_param[0].password if HEADER_FIELD_CONNECTION in header_row: db_host.connection_param[0].connection_type = im_host.connection_param[0].connection_type if HEADER_FIELD_PORT in header_row: db_host.connection_param[0].port_number = im_host.connection_param[0].port_number else: # Add the import host db_session.add(im_host) if error: return jsonify({'status': error}) else: db_session.commit() return jsonify({'status': 'OK'})
def run_conformance_report(profile_name, match_criteria, hostnames): host_not_in_conformance = 0 host_out_dated_inventory = 0 db_session = DBSession() software_profile = get_software_profile(db_session, profile_name) if software_profile is not None: software_profile_packages = software_profile.packages.split(',') conformance_report = ConformanceReport( software_profile=software_profile.name, software_profile_packages=','.join(sorted(software_profile_packages)), match_criteria=match_criteria, hostnames=hostnames, user_id=current_user.id, created_by=current_user.username) for hostname in hostnames.split(','): host = get_host(db_session, hostname) if host: packages_to_match = [software_profile_package.replace('.pie', '') for software_profile_package in software_profile_packages] inventory_job = host.inventory_job[0] comments = '' if inventory_job is not None and inventory_job.last_successful_time is not None: comments = '(' + get_last_successful_inventory_elapsed_time(host) + ')' if inventory_job.status != JobStatus.COMPLETED: comments += ' *' host_out_dated_inventory += 1 host_packages = [] if match_criteria == 'inactive': host_packages = get_host_inactive_packages(hostname) elif match_criteria == 'active': host_packages = get_host_active_packages(hostname) missing_packages = get_missing_packages(host_packages, software_profile_packages) if missing_packages: host_not_in_conformance += 1 conformed = False if len(host_packages) > 0 and len(missing_packages) == 0: conformed = True conformance_report_entry = ConformanceReportEntry( hostname=hostname, platform='Unknown' if host.software_platform is None else host.software_platform, software='Unknown' if host.software_version is None else host.software_version, conformed='Yes' if conformed else 'No', comments=comments, host_packages=','.join(sorted(match_packages(host_packages, packages_to_match))), missing_packages=','.join(sorted(missing_packages))) else: # Flag host not found condition host_out_dated_inventory += 1 host_not_in_conformance += 1 conformance_report_entry = ConformanceReportEntry( hostname=hostname, platform='MISSING', software='MISSING', inventory_status='MISSING', last_successful_retrieval='MISSING', host_packages='MISSING', missing_packages='MISSING') conformance_report.entries.append(conformance_report_entry) conformance_report.host_not_in_conformance = host_not_in_conformance conformance_report.host_out_dated_inventory = host_out_dated_inventory db_session.add(conformance_report) db_session.commit() else: return jsonify({'status': 'Unable to locate the software profile %s' % profile_name}) purge_old_conformance_reports(db_session) return jsonify({'status': 'OK'})
def batch_schedule_install(): """ For batch scheduled installation. """ if not can_install(current_user): abort(401) db_session = DBSession() form = ScheduleInstallForm(request.form) # Fills the selections fill_regions(db_session, form.region.choices) fill_dependencies(form.dependency.choices) fill_custom_command_profiles(db_session, form.custom_command_profile.choices) return_url = get_return_url(request, 'home') if request.method == 'POST': # and form.validate(): """ f = request.form for key in f.keys(): for value in f.getlist(key): print(key,":",value) """ # Retrieves from the multi-select box hostnames = form.hidden_selected_hosts.data.split(',') install_action = form.install_action.data custom_command_profile_ids = [ str(i) for i in form.custom_command_profile.data ] if hostnames is not None: for hostname in hostnames: host = get_host(db_session, hostname) if host is not None: db_session = DBSession() scheduled_time = form.scheduled_time_UTC.data software_packages = form.software_packages.data.split() server_id = form.hidden_server.data server_directory = form.hidden_server_directory.data pending_downloads = form.hidden_pending_downloads.data.split( ) # If only one install_action, accept the selected dependency if any dependency = 0 if len(install_action) == 1: # No dependency when it is 0 (a digit) if not form.dependency.data.isdigit(): prerequisite_install_job = get_last_install_action( db_session, form.dependency.data, host.id) if prerequisite_install_job is not None: dependency = prerequisite_install_job.id create_or_update_install_job( db_session=db_session, host_id=host.id, install_action=install_action[0], custom_command_profile_ids= custom_command_profile_ids, scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, pending_downloads=pending_downloads, dependency=dependency, created_by=current_user.username) else: # The dependency on each install action is already indicated in the implicit ordering # in the selector. If the user selected Pre-Upgrade and Install Add, Install Add (successor) # will have Pre-Upgrade (predecessor) as the dependency. dependency = 0 for one_install_action in install_action: new_install_job = create_or_update_install_job( db_session=db_session, host_id=host.id, install_action=one_install_action, scheduled_time=scheduled_time, custom_command_profile_ids= custom_command_profile_ids, software_packages=software_packages, server_id=server_id, server_directory=server_directory, pending_downloads=pending_downloads, dependency=dependency, created_by=current_user.username) dependency = new_install_job.id return redirect(url_for(return_url)) else: # Initialize the hidden fields form.hidden_server.data = -1 form.hidden_server_name.data = '' form.hidden_server_directory.data = '' form.hidden_pending_downloads.data = '' return render_template('schedule_install.html', form=form, system_option=SystemOption.get(db_session), server_time=datetime.datetime.utcnow(), return_url=return_url)
def handle_schedule_install_form(request, db_session, hostname, install_job=None): host = get_host(db_session, hostname) if host is None: abort(404) return_url = get_return_url(request, 'host_dashboard.home') form = HostScheduleInstallForm(request.form) # Retrieves all the install jobs for this host. This will allow # the user to select which install job this install job can depend on. install_jobs = db_session.query(InstallJob).filter( InstallJob.host_id == host.id).order_by( InstallJob.scheduled_time.asc()).all() region_servers = host.region.servers # Returns all server repositories if the region does not have any server repository designated. if is_empty(region_servers): region_servers = get_server_list(db_session) # Fills the selections fill_servers(form.server_dialog_server.choices, region_servers) fill_servers(form.server_modal_dialog_server.choices, region_servers) fill_servers(form.cisco_dialog_server.choices, region_servers, False) fill_dependency_from_host_install_jobs( form.dependency.choices, install_jobs, (-1 if install_job is None else install_job.id)) fill_custom_command_profiles(db_session, form.custom_command_profile.choices) if request.method == 'POST': if install_job is not None: # In Edit mode, the install_action UI on HostScheduleForm is disabled (not allow to change). # Thus, there will be no value returned by form.install_action.data. So, re-use the existing ones. install_action = [install_job.install_action] else: install_action = form.install_action.data scheduled_time = form.scheduled_time_UTC.data software_packages = form.software_packages.data.split() server_id = form.hidden_server.data server_directory = form.hidden_server_directory.data pending_downloads = form.hidden_pending_downloads.data.split() custom_command_profile_ids = [ str(i) for i in form.custom_command_profile.data ] # install_action is a list object which may contain multiple install actions. # If only one install_action, accept the selected dependency if any if len(install_action) == 1: dependency = int(form.dependency.data) create_or_update_install_job( db_session=db_session, host_id=host.id, install_action=install_action[0], scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, pending_downloads=pending_downloads, custom_command_profile_ids=custom_command_profile_ids, dependency=dependency, created_by=current_user.username, install_job=install_job) else: # The dependency on each install action is already indicated in the implicit ordering in the selector. # If the user selected Pre-Upgrade and Install Add, Install Add (successor) will # have Pre-Upgrade (predecessor) as the dependency. dependency = 0 for one_install_action in install_action: new_install_job = create_or_update_install_job( db_session=db_session, host_id=host.id, install_action=one_install_action, scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, pending_downloads=pending_downloads, custom_command_profile_ids=custom_command_profile_ids, dependency=dependency, created_by=current_user.username, install_job=install_job) dependency = new_install_job.id return redirect(url_for(return_url, hostname=hostname)) elif request.method == 'GET': # Initialize the hidden fields form.hidden_server.data = -1 form.hidden_selected_hosts.data = '' form.hidden_server_name.data = '' form.hidden_server_directory.data = '' form.hidden_pending_downloads.data = '' form.hidden_edit.data = install_job is not None # In Edit mode if install_job is not None: form.install_action.data = install_job.install_action if install_job.server_id is not None: form.hidden_server.data = install_job.server_id server = get_server_by_id(db_session, install_job.server_id) if server is not None: form.hidden_server_name.data = server.hostname form.hidden_server_directory.data = '' if install_job.server_directory is None else install_job.server_directory form.hidden_pending_downloads.data = '' if install_job.pending_downloads is None else install_job.pending_downloads # Form a line separated list for the textarea if install_job.packages is not None: form.software_packages.data = '\n'.join( install_job.packages.split(',')) form.dependency.data = str(install_job.dependency) if install_job.scheduled_time is not None: form.scheduled_time_UTC.data = get_datetime_string( install_job.scheduled_time) if install_job.custom_command_profile_ids: ids = [ int(id) for id in install_job.custom_command_profile_ids.split(',') ] form.custom_command_profile.data = ids return render_template('host/schedule_install.html', form=form, system_option=SystemOption.get(db_session), host=host, server_time=datetime.datetime.utcnow(), install_job=install_job, return_url=return_url)
def api_delete_install_job(request): validate_url_parameters(request, [KEY_ID, KEY_HOSTNAME, KEY_STATUS]) clauses = [] db_session = DBSession id = request.args.get(KEY_ID) hostname = request.args.get(KEY_HOSTNAME) status = request.args.get(KEY_STATUS) if id: install_jobs = db_session.query(InstallJob).filter(InstallJob.id == id).all() if len(install_jobs) == 0: raise ValueError("Install job id '{}' does not exist in the database.".format(id)) else: if hostname: host = get_host(db_session, hostname) if host: clauses.append(InstallJob.host_id == host.id) else: raise ValueError("Host '{}' does not exist in the database.".format(hostname)) if status: if status not in [JobStatus.SCHEDULED, JobStatus.FAILED]: raise ValueError("Invalid value for status: must be 'failed' or 'scheduled'.") clauses.append(InstallJob.status == (None if status == JobStatus.SCHEDULED else status)) install_jobs = get_install_jobs(InstallJob, db_session, clauses) rows = [] error_found = False for install_job in install_jobs: try: row = dict() row[KEY_ID] = install_job.id row[KEY_INSTALL_ACTION] = install_job.install_action host = get_host_by_id(db_session, install_job.host_id) if host is not None: row[KEY_HOSTNAME] = host.hostname # Only scheduled and failed jobs are deletable. if install_job.status is None or install_job.status == JobStatus.FAILED: db_session.delete(install_job) # If hostname is not specified, go ahead and delete all the install job's dependencies. # Otherwise, the dependencies should have already been selected for deletion. deleted_jobs = delete_install_job_dependencies(db_session, id) if hostname is None else [] db_session.commit() if len(deleted_jobs) > 0: row[KEY_DELETED_DEPENDENCIES] = deleted_jobs row[RESPONSE_STATUS] = APIStatus.SUCCESS else: raise ValueError("Unable to delete install job '{}' as it is in progress.".format(install_job.id)) 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: {KEY_INSTALL_JOB_LIST: rows}}), (HTTP_OK if not error_found else HTTP_MULTI_STATUS_ERROR)
def migration(): # only operator and above can schedule migration if not can_install(current_user): render_template('user/not_authorized.html', user=current_user) # temp_user_dir = create_temp_user_directory(current_user.username) # config_file_path = os.path.normpath(os.path.join(temp_user_dir, "config_conversion")) # create_directory(config_file_path) # current_app.config['UPLOAD_FOLDER'] = config_file_path # print "current_app.config.get('UPLOAD_FOLDER') = " + current_app.config.get('UPLOAD_FOLDER') db_session = DBSession() return_url = get_return_url(request, 'install_dashboard.home') schedule_form = init_schedule_form(db_session, request, get=request.method == 'GET') config_form = init_config_form(db_session, request, get=request.method == 'GET') if request.method == 'POST': print(str(config_form.data)) if config_form.hidden_submit_config_form.data == "True": return convert_config(db_session, request, 'asr9k_64_migrate/migration.html', schedule_form) # Retrieves from the multi-select box hostnames = schedule_form.hidden_hosts.data.split(',') install_action = schedule_form.install_action.data if hostnames is not None: print(str(schedule_form.data)) print(str(hostnames)) dependency_list = schedule_form.hidden_dependency.data.split(',') index = 0 for hostname in hostnames: host = get_host(db_session, hostname) if host is not None: db_session = DBSession() scheduled_time = schedule_form.scheduled_time_UTC.data software_packages = schedule_form.hidden_software_packages.data.split( ) server_id = schedule_form.hidden_server.data server_directory = schedule_form.hidden_server_directory.data custom_command_profile_ids = [ str(i) for i in schedule_form.custom_command_profile.data ] if InstallAction.MIGRATION_AUDIT in install_action: host.context[0].data['hardware_audit_version'] = \ schedule_form.hidden_hardware_audit_version.data if InstallAction.PRE_MIGRATE in install_action: host.context[0].data[ 'config_filename'] = schedule_form.hidden_config_filename.data host.context[0].data[ 'override_hw_req'] = schedule_form.hidden_override_hw_req.data # If the dependency is a previous job id, it's non-negative int string. if int(dependency_list[index]) >= 0: dependency = dependency_list[index] # In this case, the dependency is '-1', which means no dependency for the first install action else: dependency = 0 # The dependency for the first install action depends on dependency_list[index]. # The dependency for each install action following first is indicated by the implicit # ordering in the selector. If the user selected Pre-Migrate and Migrate, # Migrate (successor) will have Pre-Migrate (predecessor) as the dependency. for i in xrange(0, len(install_action)): new_install_job = create_or_update_install_job( db_session=db_session, host_id=host.id, install_action=install_action[i], scheduled_time=scheduled_time, software_packages=software_packages, server_id=server_id, server_directory=server_directory, custom_command_profile_ids= custom_command_profile_ids, dependency=dependency) print( "dependency for install_action = {} is {}".format( install_action[i], str(dependency))) dependency = new_install_job.id index += 1 return redirect(url_for(return_url)) else: return render_template( 'asr9k_64_migrate/migration.html', schedule_form=schedule_form, install_action=get_install_migrations_dict(), server_time=datetime.datetime.utcnow(), system_option=SystemOption.get(db_session), config_form=config_form, input_filename="", err_msg="", )
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 run_conformance_report(profile_name, match_criteria, hostnames): host_not_in_conformance = 0 host_out_dated_inventory = 0 db_session = DBSession() software_profile = get_software_profile(db_session, profile_name) if software_profile is not None: software_profile_packages = software_profile.packages.split(',') conformance_report = ConformanceReport( software_profile=software_profile.name, software_profile_packages=','.join( sorted(software_profile_packages)), match_criteria=match_criteria, hostnames=hostnames, user_id=current_user.id, created_by=current_user.username) for hostname in hostnames.split(','): host = get_host(db_session, hostname) if host: packages_to_match = [ software_profile_package.replace('.pie', '') for software_profile_package in software_profile_packages ] inventory_job = host.inventory_job[0] comments = '' if inventory_job is not None and inventory_job.last_successful_time is not None: comments = '(' + get_last_successful_inventory_elapsed_time( host) + ')' if inventory_job.status != JobStatus.COMPLETED: comments += ' *' host_out_dated_inventory += 1 host_packages = [] if match_criteria == 'inactive': host_packages = get_host_inactive_packages(hostname) elif match_criteria == 'active': host_packages = get_host_active_packages(hostname) missing_packages = get_missing_packages( host_packages, software_profile_packages) if missing_packages: host_not_in_conformance += 1 conformed = False if len(host_packages) > 0 and len(missing_packages) == 0: conformed = True conformance_report_entry = ConformanceReportEntry( hostname=hostname, platform='Unknown' if host.software_platform is None else host.software_platform, software='Unknown' if host.software_version is None else host.software_version, conformed='Yes' if conformed else 'No', comments=comments, host_packages=','.join( sorted(match_packages(host_packages, packages_to_match))), missing_packages=','.join(sorted(missing_packages))) else: # Flag host not found condition host_out_dated_inventory += 1 host_not_in_conformance += 1 conformance_report_entry = ConformanceReportEntry( hostname=hostname, platform='MISSING', software='MISSING', inventory_status='MISSING', last_successful_retrieval='MISSING', host_packages='MISSING', missing_packages='MISSING') conformance_report.entries.append(conformance_report_entry) conformance_report.host_not_in_conformance = host_not_in_conformance conformance_report.host_out_dated_inventory = host_out_dated_inventory db_session.add(conformance_report) db_session.commit() else: return jsonify({ 'status': 'Unable to locate the software profile %s' % profile_name }) purge_old_conformance_reports(db_session) return jsonify({'status': 'OK'})
def api_host(hostname): db_session = DBSession() host = get_host(db_session, hostname) return get_host_json([host], request)
def run_conformance_report(db_session, software_profile, match_criteria, hostnames): """ software_profile: SoftwareProfile instance hostnames: a list of hostnames """ host_not_in_conformance = 0 host_out_dated_inventory = 0 software_profile_packages = software_profile.packages.split(',') conformance_report = ConformanceReport( software_profile=software_profile.name, software_profile_packages=','.join(sorted(software_profile_packages)), match_criteria=match_criteria, hostnames=','.join(hostnames), user_id=current_user.id, created_by=current_user.username) software_profile_package_dict = fixup_software_profile_packages( software_profile_packages) for hostname in hostnames: host = get_host(db_session, hostname) if host: inventory_job = host.inventory_job[0] comments = '' if inventory_job is not None and inventory_job.last_successful_time is not None: comments = '(' + get_last_successful_inventory_elapsed_time( host) + ')' if inventory_job.status != JobStatus.COMPLETED: comments += ' *' host_out_dated_inventory += 1 host_packages = [] if match_criteria == 'inactive': host_packages = get_host_inactive_packages(hostname) elif match_criteria == 'active': host_packages = get_host_active_packages(hostname) missing_packages = get_missing_packages( host_packages, software_profile_package_dict) if missing_packages: host_not_in_conformance += 1 conformed = False if len(host_packages) > 0 and len(missing_packages) == 0: conformed = True conformance_report_entry = ConformanceReportEntry( hostname=hostname, software_platform=UNKNOWN if host.software_platform is None else host.software_platform, software_version=UNKNOWN if host.software_version is None else host.software_version, conformed=HostConformanceStatus.CONFORM if conformed else HostConformanceStatus.NON_CONFORM, comments=comments, host_packages=','.join( sorted( get_match_result( host_packages, software_profile_package_dict.values()))), missing_packages=','.join(sorted(missing_packages))) else: # Flag host not found condition host_out_dated_inventory += 1 host_not_in_conformance += 1 conformance_report_entry = ConformanceReportEntry( hostname=hostname, software_platform='MISSING', software_version='MISSING', host_packages='MISSING', missing_packages='MISSING') conformance_report.entries.append(conformance_report_entry) conformance_report.host_not_in_conformance = host_not_in_conformance conformance_report.host_out_dated_inventory = host_out_dated_inventory db_session.add(conformance_report) db_session.commit() purge_old_conformance_reports(db_session) return jsonify({'status': 'OK'})
def api_create_hosts(request): """ POST: http://localhost:5000/api/v1/hosts BODY: [ {'hostname': 'My Host 1', 'region': 'SJ Labs', 'roles': 'PE', 'connection_type': 'telnet', 'host_or_ip': '172.28.98.2', 'username': '******', 'password': '******', 'enable_password': '******', 'location': 'building 20' } ] RETURN: {"api_response": { "host_list": [ {"status": "SUCCESS", "hostname": "My Host 1"}, {"status": "SUCCESS", "hostname": "My Host 2"} ] } } """ rows = [] db_session = DBSession() error_found = False # Pre-fetched information to speed up bulk host creation. region_dict = get_region_name_to_id_dict(db_session) jump_host_dict = get_jump_host_name_to_id_dict(db_session) software_profile_dict = get_software_profile_name_to_id_dict(db_session) json_list = convert_json_request_to_list(request) for data in json_list: row = dict() try: validate_required_keys_in_dict(data, [KEY_HOSTNAME]) hostname = get_acceptable_string(data.get(KEY_HOSTNAME)) row[KEY_HOSTNAME] = hostname if hostname is None or len(hostname) == 0: raise ValueError("'{}' is an invalid hostname.".format( data.get(KEY_HOSTNAME))) validate_acceptable_keys_in_dict(data, [ KEY_HOSTNAME, KEY_REGION, KEY_LOCATION, KEY_ROLES, KEY_SOFTWARE_PROFILE, KEY_CONNECTION_TYPE, KEY_TS_OR_IP, KEY_PORT_NUMBER, KEY_USERNAME, KEY_PASSWORD, KEY_ENABLE_PASSWORD, KEY_JUMP_HOST ]) host = get_host(db_session, hostname) if host is None: # These are the required fields for a new host creation. validate_required_keys_in_dict( data, [KEY_REGION, KEY_CONNECTION_TYPE, KEY_TS_OR_IP]) value = get_id_from_value('Region', region_dict, data, KEY_REGION) region_id = value if value is not None else \ (None if host is None else host.region_id) value = get_id_from_value('Jump host', jump_host_dict, data, KEY_JUMP_HOST) jump_host_id = value if value is not None else \ (None if host is None else host.connection_param[0].jump_host_id) value = get_id_from_value('Software profile', software_profile_dict, data, KEY_SOFTWARE_PROFILE) software_profile_id = value if value is not None else \ (None if host is None else host.software_profile_id) connection_type = data.get(KEY_CONNECTION_TYPE) if connection_type is not None: if connection_type not in [ ConnectionType.SSH, ConnectionType.TELNET ]: raise ValueError( 'Connection Type must be either telnet or ssh') else: connection_type = None if host is None else host.connection_param[ 0].connection_type roles = convert_value_to_list(data, KEY_ROLES) roles = ','.join(roles) if roles is not None else \ (None if host is None else host.roles) host_or_ip = convert_value_to_list(data, KEY_TS_OR_IP) host_or_ip = ','.join(host_or_ip) if host_or_ip is not None else \ (None if host is None else host.connection_param[0].host_or_ip) port_number = convert_value_to_list(data, KEY_PORT_NUMBER) port_number = ','.join(str(p) for p in port_number) if port_number is not None else \ (None if host is None else host.connection_param[0].port_number) location = data.get(KEY_LOCATION) if data.get(KEY_LOCATION ) is not None else \ (None if host is None else host.location) username = data.get(KEY_USERNAME) if data.get(KEY_USERNAME) is not None else \ (None if host is None else host.connection_param[0].username) password = data.get(KEY_PASSWORD) if data.get(KEY_PASSWORD) is not None else \ (None if host is None else host.connection_param[0].password) enable_password = data.get(KEY_ENABLE_PASSWORD) if data.get(KEY_ENABLE_PASSWORD) is not None else \ (None if host is None else host.connection_param[0].enable_password) create_or_update_host(db_session=db_session, hostname=hostname, region_id=region_id, location=location, roles=roles, software_profile_id=software_profile_id, connection_type=connection_type, host_or_ip=host_or_ip, username=username, password=password, enable_password=enable_password, port_number=port_number, jump_host_id=jump_host_id, created_by=g.api_user.username, host=host) 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) # end loop return jsonify(**{RESPONSE_ENVELOPE: { 'host_list': rows }}), (HTTP_OK if not error_found else HTTP_MULTI_STATUS_ERROR)
def api_import_hosts(): region_id = int(request.form['region_id']) jump_host_id = int(request.form['jump_host_id']) software_profile_id = int(request.form['software_profile_id']) data_list = request.form['data_list'] db_session = DBSession() if region_id == -1: return jsonify({'status': 'Region has not been specified.'}) if region_id > 0: region = get_region_by_id(db_session, region_id) if region is None: return jsonify({'status': 'Region is no longer exists in the database.'}) if jump_host_id > 0: jump_host = get_jump_host_by_id(db_session, jump_host_id) if jump_host is None: return jsonify({'status': 'Jump Host is no longer exists in the database.'}) if software_profile_id > 0: software_profile = get_software_profile_by_id(db_session, software_profile_id) if software_profile is None: return jsonify({'status': 'Software Profile is no longer exists in the database.'}) error = [] reader = csv.reader(data_list.splitlines(), delimiter=',') header_row = next(reader) # header_row: ['hostname', 'location', 'roles', 'ip', 'username', 'password', 'connection', 'port'] # Check mandatory data fields if HEADER_FIELD_HOSTNAME not in header_row: error.append('"hostname" is missing in the header.') if HEADER_FIELD_IP not in header_row: error.append('"ip" is missing in the header.') if HEADER_FIELD_CONNECTION not in header_row: error.append('"connection" is missing in the header.') for header_field in header_row: if header_field not in HEADER_FIELDS: error.append('"' + header_field + '" is not a correct header field.') if error: return jsonify({'status': '\n'.join(error)}) error = [] data_list = list(reader) region_dict = get_region_name_to_id_dict(db_session) # Check if each row has the same number of data fields as the header row = 2 for row_data in data_list: if len(row_data) != len(header_row): error.append('line {} has wrong number of data fields - {}.'.format(row, row_data)) else: hostname = get_acceptable_string(get_row_data(row_data, header_row, HEADER_FIELD_HOSTNAME)) if is_empty(hostname): error.append('line {} has invalid hostname - {}.'.format(row, row_data)) # Validate the connection type connection_type = get_row_data(row_data, header_row, HEADER_FIELD_CONNECTION) if is_empty(connection_type) or connection_type not in [ConnectionType.TELNET, ConnectionType.SSH]: error.append('line {} has a wrong connection type (should either be "telnet" or "ssh") - {}.'.format(row, row_data)) region_name = get_acceptable_string(get_row_data(row_data, header_row, HEADER_FIELD_REGION)) if region_name is not None: # No blank region is allowed if len(region_name) == 0: error.append('line {} has no region specified - {}.'.format(row, row_data)) else: if region_name not in region_dict.keys(): # Create the new region try: region = Region(name=region_name, created_by=current_user.username) db_session.add(region) db_session.commit() # Add to region dictionary for caching purpose. region_dict[region_name] = region.id except Exception as e: logger.exception('api_import_hosts() hit exception') error.append('Unable to create region {} - {}.'.format(region_name, e.message)) row += 1 if error: return jsonify({'status': '\n'.join(error)}) # Import the data row = 2 for row_data in data_list: try: created_by = current_user.username hostname = get_acceptable_string(get_row_data(row_data, header_row, HEADER_FIELD_HOSTNAME)) # Check if the host already exists in the database. host = get_host(db_session, hostname) region_name = get_acceptable_string(get_row_data(row_data, header_row, HEADER_FIELD_REGION)) if region_name is None: alternate_region_id = region_id else: alternate_region_id = region_dict[region_name] location = get_row_data(row_data, header_row, HEADER_FIELD_LOCATION) if host and location is None: location = host.location roles = get_row_data(row_data, header_row, HEADER_FIELD_ROLES) if host and roles is None: roles = host.roles host_or_ip = get_row_data(row_data, header_row, HEADER_FIELD_IP) if host and host_or_ip is None: host_or_ip = host.connection_param[0].host_or_ip connection_type = get_row_data(row_data, header_row, HEADER_FIELD_CONNECTION) if host and connection_type is None: connection_type = host.connection_param[0].connection_type username = get_row_data(row_data, header_row, HEADER_FIELD_USERNAME) if host and username is None: username = host.connection_param[0].username password = get_row_data(row_data, header_row, HEADER_FIELD_PASSWORD) if host and password is None: password = host.connection_param[0].password enable_password = get_row_data(row_data, header_row, HEADER_FIELD_ENABLE_PASSWORD) if host and enable_password is None: enable_password = host.connection_param[0].enable_password port_number = get_row_data(row_data, header_row, HEADER_FIELD_PORT) if host and port_number is None: port_number = host.connection_param[0].port_number # If no software profile is selected, retain the existing one instead of overwriting it. if host and (software_profile_id is None or software_profile_id <= 0): alternate_software_profile_id = host.software_profile_id else: alternate_software_profile_id = software_profile_id # If no jump host is selected, retain the existing one instead of overwriting it. if host and (jump_host_id is None or jump_host_id <= 0): alternate_jump_host_id = host.connection_param[0].jump_host_id else: alternate_jump_host_id = jump_host_id create_or_update_host(db_session, hostname, alternate_region_id, location, roles, alternate_software_profile_id, connection_type, host_or_ip, username, password, enable_password, port_number, alternate_jump_host_id, created_by, host) except Exception as e: return jsonify({'status': 'Line {} - {} - {}.'.format(row, e.message, row_data)}) row += 1 return jsonify({'status': 'OK'})