Example #1
0
def prepare_scan(source_type, cleanup):
    """Prepare a scan from the 'sources' section of config file.

    :param source_type: The scan will be configured to use one source, of the
        type specified with this parameter. Uses ``get_network_source`` to
        retreive a source of this type from the config file.

    :param cleanup: The "cleanup" list that tests use to destroy objects after
        a test has run. The "cleanup" list is provided by the py.test fixture
        of the same name defined in camayoc/tests/qpc/conftest.py.

    This scan is not meant for testing the results of the scan, rather for
    functional tests that test the ability to effect the state of the scan,
    for example if you can restart a paused scan.

    :returns: camayoc.qpc_models.Scan configured for the network source found
       in the config file.
    """
    src = get_source(source_type, cleanup)
    if not src:
        return
    scn = Scan(scan_type="inspect", source_ids=[src._id])
    scn.create()
    cleanup.append(scn)
    return scn
Example #2
0
def run_scan(
    scan,
    disabled_optional_products,
    enabled_extended_product_search,
    cleanup,
    scan_type="inspect",
):
    """Scan a machine and cache any available results.

    If errors are encountered, save those and they can be included
    in test results.
    """
    src_ids = scan["source_ids"]
    scan_name = scan["name"]
    SCAN_DATA[scan_name] = {
        "scan_id": None,  # scan id
        "scan_job_id": None,  # scan job id
        "final_status": None,  # Did the scan job contain any failed tasks?
        "scan_results": None,  # Number of systems reached, etc
        "report_id": None,  # so we can retrieve report
        "connection_results": None,  # details about connection scan
        "inspection_results": None,  # details about inspection scan
        "errors": [],
        "expected_products": scan["expected_products"],
        "source_id_to_hostname": scan["source_id_to_hostname"],
    }
    try:
        scan = Scan(
            source_ids=src_ids,
            scan_type=scan_type,
            disabled_optional_products=disabled_optional_products,
            enabled_extended_product_search=enabled_extended_product_search,
        )
        scan.create()
        cleanup.append(scan)
        scanjob = ScanJob(scan_id=scan._id)
        scanjob.create()
        SCAN_DATA[scan_name]["scan_id"] = scan._id
        SCAN_DATA[scan_name]["scan_job_id"] = scanjob._id
        wait_until_state(scanjob, state="stopped")
        SCAN_DATA[scan_name]["final_status"] = scanjob.status()
        SCAN_DATA[scan_name]["scan_results"] = scanjob.read().json()
        SCAN_DATA[scan_name]["report_id"] = scanjob.read().json().get("report_id")
        if scan_type == "inspect":
            SCAN_DATA[scan_name]["task_results"] = scanjob.read().json().get("tasks")
            SCAN_DATA[scan_name]["inspection_results"] = (
                scanjob.inspection_results().json().get("results")
            )
    except (requests.HTTPError, WaitTimeError) as e:
        SCAN_DATA[scan_name]["errors"].append("{}".format(pformat(str(e))))
Example #3
0
def test_scan_with_optional_products(scan_type, shared_client, cleanup):
    """Create a scan with disabled optional products.

    :id: 366604ed-e423-4140-b0d8-38626e264688
    :description: Perform a scan and disable an optional product.
    :steps:
        1) Create a network credential
        2) Create network source using the network credential.
        3) Create a scan using the network source. When creating the scan
           disable the optional products.
    :expectedresults: The scan is created.
    """
    num_products = random.randint(0, len(QPC_OPTIONAL_PRODUCTS))
    product_combinations = combinations(QPC_OPTIONAL_PRODUCTS, num_products)
    for combo in product_combinations:
        source_ids = []
        for _ in range(random.randint(1, 10)):
            src_type = random.choice(QPC_SOURCE_TYPES)
            src = gen_valid_source(cleanup, src_type, "localhost")
            source_ids.append(src._id)
        scan = Scan(source_ids=source_ids, scan_type=scan_type, client=shared_client)
        products = {p: True for p in QPC_OPTIONAL_PRODUCTS if p not in combo}
        products.update({p: False for p in combo})
        scan.options.update({OPTIONAL_PROD: products})
        scan.create()
        cleanup.append(scan)
        assert scan.equivalent(scan.read().json())
Example #4
0
def test_negative_disable_optional_products(scan_type, shared_client, cleanup):
    """Attempt to disable optional products with non-acceptable booleans.

    :id: 2adb483c-578d-4131-b426-9f772c1803de
    :description: Create a scan with bad input for optional products
    :steps:
        1) Create a network credential
        2) Create network source using the network credential.
        3) Create a scan using the network source. When creating the scan
           disable the optional products with bad values.
    :expectedresults: The scan is not created.
    """
    num_products = random.randint(1, len(QPC_OPTIONAL_PRODUCTS))
    product_combinations = combinations(QPC_OPTIONAL_PRODUCTS, num_products)
    for combo in product_combinations:
        source_ids = []
        for _ in range(random.randint(1, 10)):
            src_type = random.choice(QPC_SOURCE_TYPES)
            src = gen_valid_source(cleanup, src_type, "localhost")
            source_ids.append(src._id)
        scan = Scan(source_ids=source_ids, scan_type=scan_type, client=shared_client)
        products = {p: True for p in QPC_OPTIONAL_PRODUCTS if p not in combo}
        bad_choice = random.choice(["hamburger", "87", 42, "*"])
        products.update({p: bad_choice for p in combo})
        scan.options.update({OPTIONAL_PROD: products})
        echo_client = api.Client(response_handler=api.echo_handler)
        scan.client = echo_client
        create_response = scan.create()
        if create_response.status_code == 201:
            cleanup.append(scan)
            raise AssertionError(
                "Optional products should be disabled and\n"
                "enabled with booleans. If invalid input is given, the user\n"
                "should be alerted."
                "The following data was provided: {}".format(products)
            )
        assert create_response.status_code == 400
        message = create_response.json().get("options", {})
        assert message.get(OPTIONAL_PROD) is not None
Example #5
0
 def test_equivalent(self):
     """If a hostname is specified in the config file, we use it."""
     with mock.patch.object(config, "_CONFIG", self.config):
         scn = Scan(source_ids=[153],
                    scan_type="connect",
                    name=MOCK_SCAN["name"])
         scn._id = MOCK_SCAN["id"]
         self.assertTrue(scn.equivalent(MOCK_SCAN))
         self.assertTrue(scn.equivalent(scn))
         with self.assertRaises(TypeError):
             scn.equivalent([])
Example #6
0
def test_delete_with_dependencies(src_type, cleanup, shared_client):
    """Test that cannot delete sources if other objects depend on them.

    :id: 76d79090-a3f7-4750-a8b8-eaf6c2ed4b89
    :description: Test that sources cannot be deleted if they are members
        of a scan.
    :steps:
        1) Create a valid source and one or more scans that use it.
        2) Attempt to delete the source, this should fail
        3) Delete the scan(s)
        4) Assert that we can now delete the source
    :expectedresults: The source is not created
    :caseautomation: notautomated
    """
    src1 = gen_valid_source(cleanup, src_type, "localhost")
    src2 = gen_valid_source(cleanup, src_type, "localhost")
    scns = []
    for i in range(random.randint(2, 6)):
        if i % 2 == 0:
            scn = Scan(source_ids=[src1._id])
        else:
            scn = Scan(source_ids=[src1._id, src2._id])
        scns.append(scn)
        scn.create()
        cleanup.append(scn)
    src1.client = api.Client(api.echo_handler)
    # this should fail
    del_response = src1.delete()
    assert del_response.status_code == 400
    # now delete scan, and then we should be allowed to delete source
    for scn in scns:
        scn.delete()
        cleanup.remove(scn)
    src1.client = shared_client
    src1.delete()
    cleanup.remove(src1)
Example #7
0
def test_create(shared_client, cleanup, scan_type):
    """Create scan and assert it has correct values.

    :id: ee3b0bc8-1489-443e-86bb-e2a2349e9c98
    :description: Create a scan and assert that it completes
    :steps:
        1) Create a network credential
        2) Create a network source with the credential
        3) Create a scan with the network source
        4) Assert that the scan is created and all fields match the request.
    :expectedresults: A scan is created with all options set as requested.
    """
    source_ids = []
    for _ in range(random.randint(1, 10)):
        src_type = random.choice(QPC_SOURCE_TYPES)
        src = gen_valid_source(cleanup, src_type, "localhost")
        source_ids.append(src._id)
    scan = Scan(source_ids=source_ids, scan_type=scan_type, client=shared_client)
    scan.create()
    cleanup.append(scan)
    remote_scn = scan.read().json()
    assert scan.equivalent(remote_scn)
Example #8
0
def test_update(update_field, shared_client, cleanup, scan_type):
    """Create scan, then update it and assert the values are changed.

    :id: c40a64c1-346e-4fce-ad18-4090066050a1
    :description: Create a scan and assert that it completes
    :steps:
        1) Create a network credential
        2) Create a network source with the credential
        3) Create a scan with the network source
        4) Assert that the scan is created and all fields match the request.
        5) Update a field and assert that changes are made
    :expectedresults: A scan is created with all options set as requested.
    """
    source_ids = []
    for _ in range(random.randint(1, 10)):
        src_type = random.choice(QPC_SOURCE_TYPES)
        src = gen_valid_source(cleanup, src_type, "localhost")
        source_ids.append(src._id)
    scan = Scan(source_ids=source_ids, scan_type=scan_type, client=shared_client)
    scan.create()
    cleanup.append(scan)
    remote_scn = scan.read().json()
    assert scan.equivalent(remote_scn)
    if update_field == "source":
        src_type = random.choice(QPC_SOURCE_TYPES)
        src = gen_valid_source(cleanup, src_type, "localhost")
        scan.sources.append(src._id)
    if update_field == "max_concurrency":
        scan.options.update({"max_concurrecny": random.randint(1, 49)})
    if update_field == "name":
        scan.name = uuid4()
    scan.update()
    remote_scn = scan.read().json()
    assert scan.equivalent(remote_scn)