def test_get_event_by_id(self, api_conf): resp = http_get(['events'], {'page': 1, 'limit': 1}, config=api_conf) assert resp == APIResponse(200) event_id = get_event_id_from_list_resp(resp.body) resp = http_get(['events', event_id], config=api_conf) assert resp == APIResponse(200)
def test_get_system_services_endpoints(self, api_conf): """ Test system services. NOTE! This only works for the super root user, so if the api_conf isn't that user, skip. Why do we even keep the api_conf in the function argument you ask? Because it's required in order to allow for pytest mark parametrization at the class level """ api_conf_name = str(api_conf.__name__) if api_conf_name != 'get_api_conf': pytest.skip( 'System Services Endpoint only works for root user of admin account: currentUserAPIConf={}' .format(api_conf_name)) resp = http_get(['system', 'services'], config=api_conf) assert resp == APIResponse(200) services = resp.body for service in services: service_name = service.get('servicename') resp = http_get(['system', 'services', service_name], config=api_conf) assert resp == APIResponse(200) service_details = resp.body resp = http_get([ 'system', 'services', service_name, service_details[0].get('hostid') ], config=api_conf) assert resp == APIResponse(200)
def test_get_all_image_vulns_by_type(self, add_alpine_latest_image): add_resp, api_conf = add_alpine_latest_image image_id = get_image_id(add_resp) resp = http_get(['images', 'by_id', image_id, 'vuln'], config=api_conf) assert resp == APIResponse(200) wait_for_image_to_analyze(image_id, api_conf) vuln_types = resp.body for v_type in vuln_types: resp = http_get(['images', 'by_id', image_id, 'vuln', v_type], config=api_conf) assert resp == APIResponse(200)
def await_account_deletion(): """ This method is helpful for awaiting account deletion of the functional_test account, with a timeout governed by DELETE_ACCOUNT_TIMEOUT_SEC. It awaits in 5 second intervals. """ start_time_sec = time.time() result = 200 while result != 404: time.sleep(5) ft_get_account_resp = http_get(['accounts', FT_ACCOUNT]) _logger.info( "Waiting for functional_test account to fully delete. Time Elapsed={}sec" .format(int(time.time() - start_time_sec))) if not (ft_get_account_resp.code == 200 or ft_get_account_resp.code == 404): _logger.error(ft_get_account_resp) raise RequestFailedError(ft_get_account_resp.url, ft_get_account_resp.code, ft_get_account_resp.body) if time.time() - start_time_sec >= DELETE_ACCOUNT_TIMEOUT_SEC: raise TimeoutError( 'Timed out waiting for functional_test account to delete' ) result = ft_get_account_resp.code
def test_get_image_vuln_types(self, add_alpine_latest_image): add_resp, api_conf = add_alpine_latest_image image_id = get_image_id(add_resp) resp = http_get(['images', 'by_id', image_id, 'vuln'], config=api_conf) assert resp == APIResponse(200)
def test_get_registry_by_name(self, add_and_teardown_registry): add_resp, api_conf = add_and_teardown_registry resp = http_get( ['registries', quote(get_registry_info()['service_name'], '')], config=api_conf) assert resp == APIResponse(200)
def test_list_events_with_level(self, api_conf, level): resp = http_get(['events'], { 'level': level, 'page': 1, 'limit': 1 }, config=api_conf) assert resp == APIResponse(200)
def test_list_events_with_resource_id(self, api_conf): resp = http_get(['events'], { 'resource_id': 'docker.io/alpine:latest', 'page': 1, 'limit': 1 }, config=api_conf) assert resp == APIResponse(200)
def test_list_events_with_resource_type(self, api_conf, r_type): resp = http_get(['events'], { 'resource_type': r_type, 'page': 1, 'limit': 1 }, config=api_conf) assert resp == APIResponse(200)
def test_list_events_with_source_servicename(self, api_conf): resp = http_get(['events'], { 'source_hostid': 'anchore-quickstart', 'page': 1, 'limit': 1 }, config=api_conf) assert resp == APIResponse(200)
def test_list_events_with_source_servicename(self, api_conf, source): resp = http_get(['events'], { 'source_servicename': source, 'page': 1, 'limit': 1 }, config=api_conf) assert resp == APIResponse(200)
def ensure_second_feed_enabled(api_conf: callable): feed_list_resp = http_get(['system', 'feeds'], config=api_conf) if feed_list_resp.code != 200: raise RequestFailedError(feed_list_resp.url, feed_list_resp.code, feed_list_resp.body) resp = http_put(['system', 'feeds', feed_list_resp.body[0].get('name')], query={'enabled': True}, config=api_conf) if resp.code != 200: raise RequestFailedError(resp.url, resp.code, resp.body)
def test_list_events_with_before(self, api_conf): resp = http_get(['events'], { 'before': str(datetime.now()), 'page': 1, 'limit': 1 }, config=api_conf) assert resp == APIResponse(200)
def test_list_image(self, add_alpine_latest_image, query): """ Atomically test list image functionality with add and teardown (by_id) implicit coverage """ add_resp, api_conf = add_alpine_latest_image resp = http_get(['images'], query=query, config=api_conf) assert resp == APIResponse(200)
def test_list_events_with_since(self, api_conf): five_min_ago = str(datetime.now() - timedelta(minutes=5)) resp = http_get(['events'], { 'since': five_min_ago, 'page': 1, 'limit': 1 }, config=api_conf) assert resp == APIResponse(200)
def test_get_archived_images_by_digest(self, create_and_teardown_archive_rule): """ Implicitly tests adding an image to the archive and deleting it """ image_resp, rule_resp, archive_resp, api_conf = create_and_teardown_archive_rule image_digest = get_image_digest(image_resp) resp = http_get(['archives', 'images', image_digest], config=api_conf) assert resp == APIResponse(200)
def test_get_image_content_ctype(self, add_alpine_latest_image): add_resp, api_conf = add_alpine_latest_image image_id = get_image_id(add_resp) wait_for_image_to_analyze(image_id, api_conf) resp = http_get(['images', 'by_id', image_id, 'content', 'os'], config=api_conf) assert resp == APIResponse(200)
def get_alpine_latest_image_os_vuln(image_id, image_digest, api_conf: callable): wait_for_image_to_analyze(image_id, api_conf) resp = http_get(['images', image_digest, 'vuln', 'os'], config=api_conf) if resp.code != 200: raise RequestFailedError(resp.url, resp.code, resp.body) return resp
def test_get_image_metadata_all_types_by_digest(self, add_alpine_latest_image): add_resp, api_conf = add_alpine_latest_image image_id = get_image_id(add_resp) wait_for_image_to_analyze(image_id, api_conf) image_digest = get_image_digest(add_resp) resp = http_get(['images', image_digest, 'metadata'], config=api_conf) assert resp == APIResponse(200) m_types = resp.body for m_type in m_types: resp = http_get(['images', image_digest, 'metadata', m_type], config=api_conf) assert resp == APIResponse(200)
def test_query_image_by_content(self, add_alpine_latest_image): add_resp, api_conf = add_alpine_latest_image # Arbitrarily get the first package from the os content response first_package = get_alpine_latest_image_os_content(get_image_id(add_resp), get_image_digest(add_resp), api_conf).body.get('content', [])[0].get('package', None) assert first_package is not None resp = http_get(['query', 'images', 'by_package'], {'name': first_package}, config=api_conf) assert resp == APIResponse(200)
def test_get_image_vulns_all_types_by_digest(self, add_alpine_latest_image, query): add_resp, api_conf = add_alpine_latest_image image_id = get_image_id(add_resp) wait_for_image_to_analyze(image_id, api_conf) image_digest = get_image_digest(add_resp) resp = http_get(['images', image_digest, 'vuln'], config=api_conf) assert resp == APIResponse(200) v_types = resp.body for v_type in v_types: resp = http_get(['images', image_digest, 'vuln', v_type], query=query, config=api_conf) assert resp == APIResponse(200)
def test_get_image_content_types_by_digest(self, add_alpine_latest_image): add_resp, api_conf = add_alpine_latest_image image_id = get_image_id(add_resp) wait_for_image_to_analyze(image_id, api_conf) image_digest = get_image_digest(add_resp) resp = http_get(['images', image_digest, 'content'], config=api_conf) assert resp == APIResponse(200)
def test_update_policy_by_id(self, create_policy_from_artifact_and_teardown): """ Just gonna do a simple update (name change) here """ policy_bundle, policy_id, api_conf = create_policy_from_artifact_and_teardown resp = http_get(['policies', policy_id], config=api_conf) policy_json = resp.body[0] policy_json['name'] = 'UpdatedName' resp = http_put(['policies', policy_id], policy_json, config=api_conf) assert resp == APIResponse(200)
def test_get_image_policy_evaluation(self, add_alpine_latest_image, query): add_resp, api_conf = add_alpine_latest_image image_id = get_image_id(add_resp) wait_for_image_to_analyze(image_id, api_conf) image_tag = get_image_tag(add_resp) query['tag'] = image_tag if query.get('policyId'): query['policyId'] = get_first_policy_id(api_conf) resp = http_get(['images', 'by_id', image_id, 'check'], {'tag': image_tag}, config=api_conf) assert resp == APIResponse(200)
def test_query_vuln(self, add_alpine_latest_image): add_resp, api_conf = add_alpine_latest_image # Arbitrarily get the first vuln from the os vuln response for alpine image try: first_vuln = get_alpine_latest_image_os_vuln(get_image_id(add_resp), get_image_digest(add_resp), api_conf).body.get('vulnerabilities', [])[0].get('vuln', None) except IndexError: self._logger.warning('No vulnerabilities found, cannot test query vulnerabilities') return assert first_vuln is not None resp = http_get(['query', 'vulnerabilities'], {'id': first_vuln}, config=api_conf) assert resp == APIResponse(200)
def test_update_registry_by_name(self, add_and_teardown_registry): add_resp, api_conf = add_and_teardown_registry get_resp = http_get( ['registries', quote(get_registry_info()['service_name'], '')], config=api_conf) assert get_resp == APIResponse(200) # copy payload from existing (password isn't provided, so re-add it) update_payload = copy.copy(get_resp.body[0]) update_payload[ 'registry_name'] = 'updated_registry_name_functional_test' update_payload['registry_pass'] = get_registry_info()['pass'] update_resp = http_put(['registries', 'docker-registry:5000'], payload=update_payload, config=api_conf) assert update_resp == APIResponse(200)
def test_get_image_secret_search(self, add_alpine_latest_image): add_resp, api_conf = add_alpine_latest_image api_conf_name = str(api_conf.__name__) if api_conf_name != 'get_api_conf': pytest.skip( 'Image Secret Search Endpoint only works for root user of admin account: currentUserAPIConf={}' .format(api_conf_name)) image_id = get_image_id(add_resp) wait_for_image_to_analyze(image_id, api_conf) image_digest = get_image_digest(add_resp) resp = http_get(['images', image_digest, 'artifacts', 'secret_search']) assert resp == APIResponse(200)
def test_disable_and_delete_system_feeds(self, api_conf): """ Since this does kinda change some of the state around feeds be sure to not re-order without considering the other feed-related tests below """ feed_list_resp = http_get(['system', 'feeds'], config=api_conf) assert feed_list_resp == APIResponse(200) # Pick arbitrary first feed to disable & then delete feeds = feed_list_resp.body feed_to_delete = feeds[0].get('name') resp = http_put(['system', 'feeds', feed_to_delete], None, {'enabled': False}, config=api_conf) assert resp == APIResponse(200) resp = http_del(['system', 'feeds', feed_to_delete], config=api_conf) assert resp == APIResponse(200)
def wait_for_image_to_analyze(image_id, api_conf: callable): status = 'analyzing' start_time_sec = time.time() while status != 'analyzed' and time.time( ) - start_time_sec < WAIT_TIMEOUT_SEC: resp = http_get(['images', 'by_id', image_id], config=api_conf) status = resp.body[0].get('analysis_status', None) if status != 'analyzed': _logger.info( 'Waiting for Image Analysis to complete. Elapsed Time={}sec'. format(int(time.time() - start_time_sec))) time.sleep(5) if time.time() - start_time_sec >= WAIT_TIMEOUT_SEC: raise TimeoutError( "Timed out waiting for Image to Analyze (timeout={}sec)".format( WAIT_TIMEOUT_SEC)) else: _logger.info('Image Analysis Complete, wait time: {}sec'.format( int(time.time() - start_time_sec)))
def test_query_image_by_vuln(self, add_alpine_latest_image): """ These tests seem to always return early because the system needs to be up and running for a while to gather feed data and analyze images. Good candidates for moving to an external test suite where an environment has been running for a while. """ add_resp, api_conf = add_alpine_latest_image # Arbitrarily get the first vuln from the os vuln response try: first_vuln = get_alpine_latest_image_os_vuln(get_image_id(add_resp), get_image_digest(add_resp), api_conf).body.get('vulnerabilities', [])[0].get('vuln', None) except IndexError: self._logger.warning('No vulnerabilities found, cannot test query images by vulnerabilities') return assert first_vuln is not None resp = http_get(['query', 'images', 'by_vulnerability'], {'vulnerability_id': first_vuln}, config=api_conf) assert resp == APIResponse(200)