def load_krb_user_from_request(request): """Load Kerberos user from current request REMOTE_USER needs to be set in environment variable, that is set by frontend Apache authentication module. """ remote_user = request.environ.get('REMOTE_USER') if not remote_user: raise Unauthorized('REMOTE_USER is not present in request.') username, realm = remote_user.split('@') user = User.find_user_by_name(username) if not user: user = User.create_user(username=username) try: groups = query_ldap_groups(username) except ldap.SERVER_DOWN as e: log.error('Cannot query groups of %s from LDAP. Error: %s', username, e.args[0]['desc']) groups = [] g.groups = groups g.user = user return user
def rebuild_if_not_exists(self, event, errata_id): """ Initiates rebuild of artifacts based on Errata advisory with `errata_id` id. :rtype: List of ErrataAdvisoryRPMsSignedEvent instances. :return: List of extra events generated to initiate the rebuild. """ db_event = db.session.query(Event).filter_by( event_type_id=EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], search_key=str(errata_id)).first() if (db_event and db_event.state != EventState.FAILED.value and not event.manual): log.debug("Ignoring Errata advisory %d - it already exists in " "Freshmaker db.", errata_id) return [] # Get additional info from Errata to fill in the needed data. errata = Errata() advisories = errata.advisories_from_event(event) if not advisories: log.error("Unknown Errata advisory %d" % errata_id) return [] log.info("Generating ErrataAdvisoryRPMsSignedEvent for Errata " "advisory %d, because its state changed to %s.", errata_id, event.advisory.state) advisory = advisories[0] new_event = ErrataAdvisoryRPMsSignedEvent( event.msg_id + "." + str(advisory.name), advisory) new_event.dry_run = event.dry_run new_event.manual = event.manual return [new_event]
def require_oidc_scope(scope): """Check if required scopes is in OIDC scopes within request""" full_scope = '{0}{1}'.format(conf.oidc_base_namespace, scope) if conf.auth_backend == "openidc" and full_scope not in g.oidc_scopes: message = 'Request does not have required scope %s' % scope log.error(message) raise Forbidden(message)
def _filter_bundles_by_pinned_related_images(self, bundle_image_nvrs): """ If the digests were not pinned by OSBS, the bundle image nvr will be filtered out. There is no need in checking pinning for every of related images, because we already know that digest points to the manifest list, because of previous filtering. :param set bundle_image_nvrs: NVRs of operator bundles :return: list of NVRs of bundle images that have at least one original related image that was rebuilt """ ret_bundle_images_nvrs = set() with koji_service(conf.koji_profile, log, dry_run=self.dry_run, login=False) as session: for nvr in bundle_image_nvrs: build = session.get_build(nvr) if not build: log.error("Could not find the build %s in Koji", nvr) continue related_images = (build.get("build", {}).get("extra", {}).get( "image", {}).get("operator_manifests", {}).get("related_images", {})) # Skip the bundle if the related images section was not populated by OSBS if related_images.get("created_by_osbs") is not True: continue ret_bundle_images_nvrs.add(nvr) return ret_bundle_images_nvrs
def load_cg_metadata(self, buildinfo): """ Fetch CG metadata.json and load the json. buildinfo may be either a int ID, a string NVR, or a map containing 'name', 'version' and 'release. """ cg_metadata_url = None try: cg_metadata_url = self.get_cg_metadata_url(buildinfo) resp = requests.get(cg_metadata_url) # url is redirected if resp.history: cg_metadata_url = resp.url return requests.get(cg_metadata_url).json() except requests.ConnectionError: raise except Exception as e: if cg_metadata_url: log.error( "Unable to load CG metadata for build (%r) from url (%s): %s", buildinfo, cg_metadata_url, str(e)) else: log.error("Unable to load CG metadata for build (%r): %s", str(e)) raise
def fetch_cve_metadata(self, cve_list): """ Fetches metadata about each CVE in `cve_list` and returns a tuple with the name of highest severity rate and the affected packages (a dictionary with product and pkg_name). See `SFM2API.THREAT_SEVERITIES` for list of possible severity rates. :param list cve_list: List of strings with CVE names. :rtype: str :return: Tuple, the first element is the name of highest severity rate occuring in CVEs from `cve_list`. The second element is a list of dicts, with "product" and "pkg_name" of the affected packages. """ max_rating = -1 affected_pkgs = [] severity = None for cve in cve_list: try: elements = self.query_sfm2(cve) except requests.exceptions.HTTPError as e: if e.response.status_code == 400: log.warning( "The request for the CVE %s to the SFM2 API seems wrong, " "impact and affected packages unknown. %s", cve, e.response.request.url) continue if e.response.status_code == 500: log.warning( "Some error occurred looking forCVE %s with SFM2 API, " "impact and affected packages unknown. %s", cve, e.response.request.url) continue raise try: severity = elements['impact'] except (IndexError, KeyError): log.warning("Some error occured looking for impact for CVE %s using SFM2 API", cve) try: affected_pkgs.extend([ {'product': item['ps_module'], 'pkg_name': item['ps_component']} for item in elements['affects'] if ( item['affected'] != "notaffected" and item['resolution'] not in ["wontfix", "ooss"])]) except (KeyError, IndexError): log.exception("Some error occured looking for affected packages for CVE %s using SFM2 API", cve) try: rating = SFM2API.THREAT_SEVERITIES.index(severity) except ValueError: log.error("Unknown threat_severity '%s' for CVE %s", severity, cve) continue max_rating = max(max_rating, rating) if max_rating == -1: return (None, affected_pkgs) return (SFM2API.THREAT_SEVERITIES[max_rating], affected_pkgs)
def poll(self): try: self.check_unfinished_koji_tasks(db.session) except _sa_disconnect_exceptions as ex: db.session.rollback() log.error("Invalid request, session is rolled back: %s", ex.orig) except Exception: msg = 'Error in poller execution:' log.exception(msg) log.info('Poller will now sleep for "{}" seconds' .format(conf.polling_interval))
def koji_service(profile=None, logger=None, login=True, dry_run=False): """A Koji service context manager that could be used with with Example:: with KojiService() as service: ... # if you want it to log something with KojiService(logger=logger) as service: ... # if you want it to use alternative Koji profile rather than the default one koji with KojiService(koji='stg', logger=logger) as service: ... """ service = KojiService(profile=profile, dry_run=dry_run) if login: if not conf.krb_auth_principal: log.error("Cannot login to Koji, krb_auth_principal not set") else: log.debug('Logging into %s with Kerberos authentication.', service.server) service.krb_login() # We are not logged in in dry run mode... if not dry_run and not service.logged_in: log.error('Could not login server %s', service.server) yield None try: yield service finally: if service.logged_in: if logger: logger.debug('Logout Koji session') service.logout()