def main(): """ The main function. It creates VmaaS application, servers, run everything.""" vmaas_app = Application() server = tornado.httpserver.HTTPServer(vmaas_app) server.bind(PUBLIC_API_PORT) num_servers = int(os.getenv("MAX_VMAAS_SERVERS", MAX_SERVERS)) server.start(num_servers) # start forking here init_logging(num_servers) LOGGER.info("Starting (version %s).", VMAAS_VERSION) # The rest stuff must be done only after forking BaseHandler.db_cache = Cache() BaseHandler.updates_api = UpdatesAPI(BaseHandler.db_cache) BaseHandler.repo_api = RepoAPI(BaseHandler.db_cache) BaseHandler.cve_api = CveAPI(BaseHandler.db_cache) BaseHandler.errata_api = ErrataAPI(BaseHandler.db_cache) BaseHandler.dbchange_api = DBChange(BaseHandler.db_cache) vmaas_app.websocket_reconnect() vmaas_app.reconnect_callback = PeriodicCallback( vmaas_app.websocket_reconnect, WEBSOCKET_RECONNECT_INTERVAL * 1000) vmaas_app.reconnect_callback.start() IOLoop.instance().start()
def setup_api(self, load_cache): """Setup ErrataAPI object from self.cache""" # WORKAROUND: tzinfo from date is lost after loading YAML errata_detail = self.cache.errata_detail[ERRATA_NAME] errata_detail_list = list(errata_detail) errata_detail_list[ERRATA_UPDATED] = errata_detail[ERRATA_UPDATED].replace(tzinfo=pytz.utc) errata_detail_list[ERRATA_ISSUED] = errata_detail[ERRATA_ISSUED].replace(tzinfo=pytz.utc) self.cache.errata_detail[ERRATA_NAME] = errata_detail_list # make errata_detail without ERRATA_UPDATED errata_detail2 = self.cache.errata_detail[ERRATA_NAME] errata_detail_list2 = list(errata_detail2) errata_detail_list2[ERRATA_UPDATED] = None self.cache.errata_detail["RHSA-W/O:MODIFIED"] = errata_detail_list2 self.errata_api = ErrataAPI(self.cache)
def load_cache_to_apis(): """Reload cache in APIs.""" BaseHandler.updates_api = UpdatesAPI(BaseHandler.db_cache) BaseHandler.repo_api = RepoAPI(BaseHandler.db_cache) BaseHandler.cve_api = CveAPI(BaseHandler.db_cache) BaseHandler.errata_api = ErrataAPI(BaseHandler.db_cache) BaseHandler.packages_api = PackagesAPI(BaseHandler.db_cache) BaseHandler.vulnerabilities_api = VulnerabilitiesAPI(BaseHandler.db_cache, BaseHandler.updates_api) BaseHandler.dbchange_api = DBChange(BaseHandler.db_cache)
def __init__(self): handlers = [ (r"/api/internal/refresh/?", RefreshHandler), # GET request (r"/api/v1/updates/?", UpdatesHandler), # POST request (r"/api/v1/updates/[a-zA-Z0-9-._:]+", UpdatesHandler), # GET request with package name (r"/api/v1/cves/?", CVEHandler), (r"/api/v1/cves/[a-zA-Z0-9*-]+", CVEHandler), (r"/api/v1/repos/?", ReposHandler), (r"/api/v1/repos/[a-zA-Z0-9*-_]+", ReposHandler), (r"/api/v1/errata/?", ErrataHandler), # POST request (r"/api/v1/errata/[a-zA-Z0-9*-:]+", ErrataHandler) # GET request ] cursor = Database().cursor() self.updatesapi = UpdatesAPI(cursor) self.cveapi = CveAPI(cursor) self.repoapi = RepoAPI(cursor) self.errataapi = ErrataAPI(cursor) tornado.web.Application.__init__(self, handlers)
class TestErrataAPI(TestBase): """TestErrataAPI class. Test ErrataAPI class.""" errata_api = None @pytest.fixture(autouse=True) def setup_api(self, load_cache): """Setup ErrataAPI object from self.cache""" # WORKAROUND: tzinfo from date is lost after loading YAML errata_detail = self.cache.errata_detail["RHSA-2018:1055"] errata_detail_list = list(errata_detail) errata_detail_list[ERRATA_UPDATED] = errata_detail[ ERRATA_UPDATED].replace(tzinfo=pytz.utc) errata_detail_list[ERRATA_ISSUED] = errata_detail[ ERRATA_ISSUED].replace(tzinfo=pytz.utc) self.cache.errata_detail["RHSA-2018:1055"] = errata_detail_list # make errata_detail without ERRATA_UPDATED errata_detail2 = self.cache.errata_detail["RHSA-2018:1055"] errata_detail_list2 = list(errata_detail2) errata_detail_list2[ERRATA_UPDATED] = None self.cache.errata_detail["RHSA-W/O:MODIFIED"] = errata_detail_list2 self.errata_api = ErrataAPI(self.cache) def test_wrong_regex(self): """Test wrong errata regex.""" with pytest.raises(Exception) as context: self.errata_api.find_errata_by_regex("*") assert "nothing to repeat" in str(context) def test_regex(self): """Test correct errata regex.""" assert self.errata_api.find_errata_by_regex("RHSA-2018:1055") == [ "RHSA-2018:1055" ] assert "RHSA-2018:1055" in self.errata_api.find_errata_by_regex( "RHSA-2018:1.*") assert len(self.errata_api.find_errata_by_regex("RHSA-2018:1.*")) > 1 def test_missing_required(self): """Test missing required property 'errata_list'.""" with pytest.raises(Exception) as context: self.errata_api.process_list(api_version="v1", data=ERRATA_JSON_BAD) assert "'errata_list' is a required property" in str(context) def test_empty_json(self): """Test errata API with empty JSON.""" with pytest.raises(Exception) as context: self.errata_api.process_list(api_version="v1", data=ERRATA_JSON_EMPTY) assert "'errata_list' is a required property" in str(context) def test_empty_errata_list(self): """Test errata API with empty 'errata_list'.""" response = self.errata_api.process_list(api_version="v1", data=ERRATA_JSON_EMPTY_LIST) assert tools.match(EMPTY_RESPONSE, response) is True def test_non_existing_errata(self): """Test errata API repsonse for non-existent errata.""" response = self.errata_api.process_list(api_version="v1", data=ERRATA_JSON_NON_EXIST) assert tools.match(EMPTY_RESPONSE, response) is True def test_schema(self): """Test schema of valid errata API response.""" response = self.errata_api.process_list(api_version="v1", data=ERRATA_JSON) assert schemas.errata_schema.validate(response) @pytest.mark.skip( "Blocked by https://github.com/RedHatInsights/vmaas/issues/419") def test_modified_since(self): """Test errata API with 'modified_since' property.""" errata = ERRATA_JSON.copy() errata["modified_since"] = str( datetime.datetime.now().replace(tzinfo=pytz.UTC)) response = self.errata_api.process_list(api_version="v1", data=errata) assert tools.match(EMPTY_RESPONSE, response) is True # without modified date errata["errata_list"] = ["RHSA-W/O:MODIFIED"] response = self.errata_api.process_list(api_version="v1", data=errata) assert tools.match(EMPTY_RESPONSE, response) is True
class TestErrataAPI(TestBase): """TestErrataAPI class. Test ErrataAPI class.""" errata_api = None @pytest.fixture(autouse=True) def setup_api(self, load_cache): """Setup ErrataAPI object from self.cache""" # WORKAROUND: tzinfo from date is lost after loading YAML errata_detail = self.cache.errata_detail[ERRATA_NAME] errata_detail_list = list(errata_detail) errata_detail_list[ERRATA_UPDATED] = errata_detail[ ERRATA_UPDATED].replace(tzinfo=pytz.utc) errata_detail_list[ERRATA_ISSUED] = errata_detail[ ERRATA_ISSUED].replace(tzinfo=pytz.utc) self.cache.errata_detail[ERRATA_NAME] = errata_detail_list # make errata_detail without ERRATA_UPDATED errata_detail2 = self.cache.errata_detail[ERRATA_NAME] errata_detail_list2 = list(errata_detail2) errata_detail_list2[ERRATA_UPDATED] = None errata_detail_list2[ERRATA_ISSUED] = None self.cache.errata_detail["RHSA-W/O:MODIFIED"] = errata_detail_list2 self.errata_api = ErrataAPI(self.cache) def test_wrong_regex(self): """Test wrong errata regex.""" with pytest.raises(Exception) as context: self.errata_api.find_errata_by_regex("*") assert "nothing to repeat" in str(context.value) def test_regex(self): """Test correct errata regex.""" assert self.errata_api.find_errata_by_regex(ERRATA_NAME) == [ ERRATA_NAME ] assert self.errata_api.find_errata_by_regex("RHBA-2015:0.*") == [ ERRATA_NAME ] def test_missing_required(self): """Test missing required property 'errata_list'.""" with pytest.raises(Exception) as context: self.errata_api.process_list(api_version="v1", data=ERRATA_JSON_BAD) assert "'errata_list' is a required property" in str(context.value) def test_empty_json(self): """Test errata API with empty JSON.""" with pytest.raises(Exception) as context: self.errata_api.process_list(api_version="v1", data=ERRATA_JSON_EMPTY) assert "'errata_list' is a required property" in str(context.value) def test_empty_errata_list(self): """Test errata API with empty 'errata_list'.""" response = self.errata_api.process_list(api_version="v1", data=ERRATA_JSON_EMPTY_LIST) assert tools.match(EMPTY_RESPONSE, response) is True def test_non_existing_errata(self): """Test errata API repsonse for non-existent errata.""" response = self.errata_api.process_list(api_version="v1", data=ERRATA_JSON_NON_EXIST) assert tools.match(EMPTY_RESPONSE, response) is True def test_errata_response(self): """Test errata API response.""" response = self.errata_api.process_list(api_version="v1", data=ERRATA_JSON) assert schemas.errata_schema.validate(response) assert ERRATA_NAME in response["errata_list"] assert tools.match(CORRECT_RESPONSE, response["errata_list"][ERRATA_NAME]) is True def test_page_size(self): """Test errata API page size""" response = self.errata_api.process_list(api_version="v1", data=ERRATA_JSON) page_size = len(response['errata_list']) assert response['page_size'] == page_size def test_modified_since(self): """Test errata API with 'modified_since' property.""" response = self.errata_api.process_list(api_version="v1", data=ERRATA_JSON_MODIFIED) modified_from_resp = parse_datetime( response['errata_list'][ERRATA_NAME]['updated']) modified_since = parse_datetime(DATE_SINCE) assert modified_from_resp >= modified_since assert DATE_SINCE == response['modified_since'] def test_modified_in_future(self): """Test CVE API with 'modified_since' property in future.""" errata = ERRATA_JSON_MODIFIED.copy() errata["modified_since"] = MODIFIED_IN_FUTURE response = self.errata_api.process_list(api_version="v1", data=errata) assert tools.match(EMPTY_RESPONSE, response) is True def test_without_modified(self): """Test errata without modified date. In response {updated: None}.""" errata = ERRATA_JSON_MODIFIED.copy() errata["errata_list"] = ["RHSA-W/O:MODIFIED"] response = self.errata_api.process_list(api_version="v1", data=errata) assert tools.match(EMPTY_RESPONSE, response) is True