badges-stg: patch badges-backend to use fasjson
Signed-off-by: Ryan Lerch <rlerch@redhat.com>
This commit is contained in:
parent
372f845509
commit
fbb5ce4367
4 changed files with 167 additions and 6 deletions
154
roles/badges/backend/files/fedbadges_utils.py
Normal file
154
roles/badges/backend/files/fedbadges_utils.py
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
""" Utilities for fedbadges that don't quite fit anywhere else. """
|
||||||
|
|
||||||
|
import types
|
||||||
|
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger("moksha.hub")
|
||||||
|
|
||||||
|
import fedmsg
|
||||||
|
import fedora.client
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# These are here just so they're available in globals()
|
||||||
|
# for compiling lambda expressions
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import fedmsg.config
|
||||||
|
import fedmsg.encoding
|
||||||
|
import fedmsg.meta
|
||||||
|
|
||||||
|
# Imports for fasjson support
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
import requests.exceptions
|
||||||
|
from gssapi import Credentials, exceptions
|
||||||
|
from requests_gssapi import HTTPSPNEGOAuth
|
||||||
|
|
||||||
|
|
||||||
|
def construct_substitutions(msg):
|
||||||
|
""" Convert a fedmsg message into a dict of substitutions. """
|
||||||
|
subs = {}
|
||||||
|
for key1 in msg:
|
||||||
|
if isinstance(msg[key1], dict):
|
||||||
|
subs.update(dict([
|
||||||
|
('.'.join([key1, key2]), val2)
|
||||||
|
for key2, val2 in construct_substitutions(msg[key1]).items()
|
||||||
|
]))
|
||||||
|
subs[key1] = msg[key1]
|
||||||
|
elif isinstance(msg[key1], basestring):
|
||||||
|
subs[key1] = msg[key1].lower()
|
||||||
|
else:
|
||||||
|
subs[key1] = msg[key1]
|
||||||
|
return subs
|
||||||
|
|
||||||
|
|
||||||
|
def format_args(obj, subs):
|
||||||
|
""" Recursively apply a substitutions dict to a given criteria subtree """
|
||||||
|
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
for key in obj:
|
||||||
|
obj[key] = format_args(obj[key], subs)
|
||||||
|
elif isinstance(obj, list):
|
||||||
|
return [format_args(item, subs) for item in obj]
|
||||||
|
elif isinstance(obj, basestring) and obj[2:-2] in subs:
|
||||||
|
obj = subs[obj[2:-2]]
|
||||||
|
elif isinstance(obj, (int, float)):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
obj = obj % subs
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
def single_argument_lambda_factory(expression, argument, name='value'):
|
||||||
|
""" Compile and execute a lambda expression with a single argument """
|
||||||
|
|
||||||
|
code = compile("lambda %s: %s" % (name, expression), __file__, "eval")
|
||||||
|
func = types.LambdaType(code, globals())()
|
||||||
|
return func(argument)
|
||||||
|
|
||||||
|
|
||||||
|
def recursive_lambda_factory(obj, arg, name='value'):
|
||||||
|
""" Given a dict, find any lambdas, compile, and execute them. """
|
||||||
|
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
for key in obj:
|
||||||
|
if key == 'lambda':
|
||||||
|
# If so, *replace* the parent dict with the result of the expr
|
||||||
|
obj = single_argument_lambda_factory(obj[key], arg, name)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
obj[key] = recursive_lambda_factory(obj[key], arg, name)
|
||||||
|
elif isinstance(obj, list):
|
||||||
|
return [recursive_lambda_factory(e, arg, name) for e in obj]
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
def graceful(default_return_value):
|
||||||
|
""" A decorator that gracefully handles exceptions. """
|
||||||
|
|
||||||
|
def decorate(method):
|
||||||
|
def inner(self, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
return method(self, *args, **kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
log.exception(e)
|
||||||
|
log.error("From method: %r self: %r args: %r kwargs: %r" % (
|
||||||
|
method, self, args, kwargs))
|
||||||
|
return default_return_value
|
||||||
|
return inner
|
||||||
|
return decorate
|
||||||
|
|
||||||
|
|
||||||
|
def notification_callback(topic, msg):
|
||||||
|
""" This is a callback called by tahrir_api whenever something
|
||||||
|
it deems important has happened.
|
||||||
|
|
||||||
|
It is just used to publish fedmsg messages.
|
||||||
|
"""
|
||||||
|
fedmsg.publish(
|
||||||
|
topic=topic,
|
||||||
|
msg=msg,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def user_exists_in_fas(config, user):
|
||||||
|
""" Return true if the user exists in FAS. """
|
||||||
|
if config.get("fasjson_base_url", False):
|
||||||
|
# fasjson_client not available in python2, so just use requests
|
||||||
|
os.environ["KRB5_CLIENT_KTNAME"] = config.get("keytab")
|
||||||
|
try:
|
||||||
|
creds = Credentials(usage="initiate")
|
||||||
|
except exceptions.GSSError as e:
|
||||||
|
log.error("GSSError trying to authenticate to fasjson", e)
|
||||||
|
gssapi_auth = HTTPSPNEGOAuth(opportunistic_auth=True, creds=creds)
|
||||||
|
session = requests.Session()
|
||||||
|
session.auth = gssapi_auth
|
||||||
|
return session.get(config['fasjson_base_url']+"users/"+user+"/").ok
|
||||||
|
else:
|
||||||
|
default_url = 'https://admin.fedoraproject.org/accounts/'
|
||||||
|
fas2 = fedora.client.AccountSystem(
|
||||||
|
base_url=config['fas_credentials'].get('base_url', default_url),
|
||||||
|
username=config['fas_credentials']['username'],
|
||||||
|
password=config['fas_credentials']['password'],
|
||||||
|
)
|
||||||
|
return bool(fas2.person_by_username(user))
|
||||||
|
|
||||||
|
def get_pagure_authors(authors):
|
||||||
|
""" Extract the name of pagure authors from
|
||||||
|
a dictionary
|
||||||
|
|
||||||
|
Args:
|
||||||
|
authors (list): A list of dict that contains fullname and name key.
|
||||||
|
"""
|
||||||
|
authors_name = []
|
||||||
|
for item in authors:
|
||||||
|
if isinstance(item, dict):
|
||||||
|
try:
|
||||||
|
authors_name.append(item["name"])
|
||||||
|
except KeyError:
|
||||||
|
raise Exception("Multiple recipients : name not found in the message")
|
||||||
|
return authors_name
|
|
@ -229,3 +229,13 @@
|
||||||
tags:
|
tags:
|
||||||
- badges
|
- badges
|
||||||
- badges/backend
|
- badges/backend
|
||||||
|
|
||||||
|
# https://raw.githubusercontent.com/fedora-infra/fedbadges/fasjson/fedbadges/utils.py
|
||||||
|
- name: hotfix fedbadges with version from fasjson branch
|
||||||
|
copy:
|
||||||
|
src: fedbadges_utils.py
|
||||||
|
dest: /usr/lib/python2.7/site-packages/fedbadges/utils.py
|
||||||
|
when: env == "staging"
|
||||||
|
tags:
|
||||||
|
- badges
|
||||||
|
- badges/backend
|
||||||
|
|
|
@ -35,16 +35,13 @@ config = {
|
||||||
# The badges backend (fedmsg-hub) uses this to build a fas cache of ircnicks
|
# The badges backend (fedmsg-hub) uses this to build a fas cache of ircnicks
|
||||||
# to fas usernames so it can act appropriately on certain message types.
|
# to fas usernames so it can act appropriately on certain message types.
|
||||||
"fas_credentials": {
|
"fas_credentials": {
|
||||||
{% if env == 'staging' %}
|
|
||||||
"base_url": "https://accounts.stg.fedoraproject.org/",
|
|
||||||
{% endif %}
|
|
||||||
"username": "{{fedoraDummyUser}}",
|
"username": "{{fedoraDummyUser}}",
|
||||||
"password": "{{fedoraDummyUserPassword}}",
|
"password": "{{fedoraDummyUserPassword}}",
|
||||||
},
|
},
|
||||||
|
|
||||||
{% if env == 'staging' %}
|
{% if env == 'staging' %}
|
||||||
"fasjson_base_url": "https://fasjson.stg.fedoraproject.org/v1/"
|
"fasjson_base_url": "https://fasjson.stg.fedoraproject.org/v1/",
|
||||||
"keytab": "/etc/krb5.badges-backend_badges-backend01.stg.iad2.fedoraproject.org.keytab"
|
"keytab": "/etc/krb5.badges-backend_badges-backend01.stg.iad2.fedoraproject.org.keytab",
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
config = {
|
config = {
|
||||||
{% if env == "staging" %}
|
{% if env == "staging" %}
|
||||||
'datanommer.sqlalchemy.url': 'postgresql://{{datanommerDBUser}}:{{datanommerDBPassword}}@db-datanommer.stg.iad2.fedoraproject.org/datanommer2',
|
'datanommer.sqlalchemy.url': 'postgresql://{{datanommerDBUser}}:{{datanommerDBPassword}}@db-datanommer01.stg.iad2.fedoraproject.org/datanommer2',
|
||||||
{% else %}
|
{% else %}
|
||||||
'datanommer.sqlalchemy.url': 'postgresql://{{datanommerDBUser}}:{{datanommerDBPassword}}@db-datanommer/datanommer',
|
'datanommer.sqlalchemy.url': 'postgresql://{{datanommerDBUser}}:{{datanommerDBPassword}}@db-datanommer/datanommer',
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue