Beispiel #1
0
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})
Beispiel #2
0
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'})
Beispiel #3
0
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'})
Beispiel #4
0
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'})
Beispiel #5
0
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'})
Beispiel #6
0
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
            }]
        })
Beispiel #7
0
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': []})
Beispiel #8
0
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})
Beispiel #9
0
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)
Beispiel #10
0
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}
    ]})
Beispiel #11
0
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})
Beispiel #12
0
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})
Beispiel #13
0
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'})
Beispiel #14
0
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'})
Beispiel #15
0
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)
Beispiel #16
0
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'})
Beispiel #17
0
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])
Beispiel #18
0
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'})
Beispiel #19
0
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})
Beispiel #20
0
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'})
Beispiel #21
0
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}]})
Beispiel #22
0
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
            }]
        })
Beispiel #23
0
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})
Beispiel #24
0
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)
Beispiel #25
0
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
                           ])
Beispiel #26
0
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)
Beispiel #27
0
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)
Beispiel #28
0
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})
Beispiel #29
0
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})
Beispiel #30
0
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})
Beispiel #31
0
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})
Beispiel #32
0
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})
Beispiel #33
0
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})
Beispiel #34
0
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})
Beispiel #35
0
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})
Beispiel #36
0
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})
Beispiel #37
0
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})
Beispiel #38
0
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})
Beispiel #39
0
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})
Beispiel #40
0
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="")
Beispiel #41
0
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="",
                               )
Beispiel #42
0
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)
Beispiel #43
0
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)
Beispiel #44
0
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'})
Beispiel #45
0
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'})
Beispiel #46
0
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)
Beispiel #47
0
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="")
Beispiel #48
0
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'})
Beispiel #49
0
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'})
Beispiel #50
0
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)
Beispiel #51
0
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)
Beispiel #52
0
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)
Beispiel #53
0
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="",
        )
Beispiel #54
0
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)
Beispiel #55
0
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'})
Beispiel #56
0
def api_host(hostname):
    db_session = DBSession()
    
    host = get_host(db_session, hostname)
    return get_host_json([host], request)
Beispiel #57
0
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'})
Beispiel #58
0
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)
Beispiel #59
0
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'})