Fix exception handling in the registry health check and make sure the user_loader is registered before the process is forked

This commit is contained in:
Joseph Schorr 2015-01-16 22:41:54 -05:00
parent e7054a8690
commit 2a89accc49
4 changed files with 58 additions and 43 deletions

26
app.py
View file

@ -5,7 +5,7 @@ import yaml
from flask import Flask as BaseFlask, Config as BaseConfig, request, Request from flask import Flask as BaseFlask, Config as BaseConfig, request, Request
from flask.ext.principal import Principal from flask.ext.principal import Principal
from flask.ext.login import LoginManager from flask.ext.login import LoginManager, UserMixin
from flask.ext.mail import Mail from flask.ext.mail import Mail
import features import features
@ -150,5 +150,29 @@ database.configure(app.config)
model.config.app_config = app.config model.config.app_config = app.config
model.config.store = storage model.config.store = storage
@login_manager.user_loader
def load_user(user_uuid):
logger.debug('User loader loading deferred user with uuid: %s' % user_uuid)
return LoginWrappedDBUser(user_uuid)
class LoginWrappedDBUser(UserMixin):
def __init__(self, user_uuid, db_user=None):
self._uuid = user_uuid
self._db_user = db_user
def db_user(self):
if not self._db_user:
self._db_user = model.get_user_by_uuid(self._uuid)
return self._db_user
def is_authenticated(self):
return self.db_user() is not None
def is_active(self):
return self.db_user().verified
def get_id(self):
return unicode(self._uuid)
def get_app_url(): def get_app_url():
return '%s://%s' % (app.config['PREFERRED_URL_SCHEME'], app.config['SERVER_HOSTNAME']) return '%s://%s' % (app.config['PREFERRED_URL_SCHEME'], app.config['SERVER_HOSTNAME'])

View file

@ -4,14 +4,17 @@ import json
import string import string
import datetime import datetime
# Register the various exceptions via decorators.
import endpoints.decorated
from flask import make_response, render_template, request, abort, session from flask import make_response, render_template, request, abort, session
from flask.ext.login import login_user, UserMixin from flask.ext.login import login_user
from flask.ext.principal import identity_changed from flask.ext.principal import identity_changed
from random import SystemRandom from random import SystemRandom
from data import model from data import model
from data.database import db from data.database import db
from app import app, login_manager, oauth_apps, dockerfile_build_queue from app import app, oauth_apps, dockerfile_build_queue, LoginWrappedDBUser
from auth.permissions import QuayDeferredPermissionUser from auth.permissions import QuayDeferredPermissionUser
from auth import scopes from auth import scopes
@ -21,7 +24,6 @@ from functools import wraps
from config import getFrontendVisibleConfig from config import getFrontendVisibleConfig
from external_libraries import get_external_javascript, get_external_css from external_libraries import get_external_javascript, get_external_css
from endpoints.notificationhelper import spawn_notification from endpoints.notificationhelper import spawn_notification
from util.useremails import CannotSendEmailException
import features import features
@ -84,34 +86,8 @@ def param_required(param_name):
return wrapper return wrapper
@login_manager.user_loader
def load_user(user_uuid):
logger.debug('User loader loading deferred user with uuid: %s' % user_uuid)
return _LoginWrappedDBUser(user_uuid)
class _LoginWrappedDBUser(UserMixin):
def __init__(self, user_uuid, db_user=None):
self._uuid = user_uuid
self._db_user = db_user
def db_user(self):
if not self._db_user:
self._db_user = model.get_user_by_uuid(self._uuid)
return self._db_user
def is_authenticated(self):
return self.db_user() is not None
def is_active(self):
return self.db_user().verified
def get_id(self):
return unicode(self._uuid)
def common_login(db_user): def common_login(db_user):
if login_user(_LoginWrappedDBUser(db_user.uuid, db_user)): if login_user(LoginWrappedDBUser(db_user.uuid, db_user)):
logger.debug('Successfully signed in as: %s (%s)' % (db_user.username, db_user.uuid)) logger.debug('Successfully signed in as: %s (%s)' % (db_user.username, db_user.uuid))
new_identity = QuayDeferredPermissionUser(db_user.uuid, 'user_uuid', {scopes.DIRECT_LOGIN}) new_identity = QuayDeferredPermissionUser(db_user.uuid, 'user_uuid', {scopes.DIRECT_LOGIN})
identity_changed.send(app, identity=new_identity) identity_changed.send(app, identity=new_identity)
@ -121,17 +97,6 @@ def common_login(db_user):
logger.debug('User could not be logged in, inactive?.') logger.debug('User could not be logged in, inactive?.')
return False return False
@app.errorhandler(model.DataModelException)
def handle_dme(ex):
logger.exception(ex)
return make_response(json.dumps({'message': ex.message}), 400)
@app.errorhandler(CannotSendEmailException)
def handle_emailexception(ex):
message = 'Could not send email. Please contact an administrator and report this problem.'
return make_response(json.dumps({'message': message}), 400)
def random_string(): def random_string():
random = SystemRandom() random = SystemRandom()
return ''.join([random.choice(string.ascii_uppercase + string.digits) for _ in range(8)]) return ''.join([random.choice(string.ascii_uppercase + string.digits) for _ in range(8)])

19
endpoints/decorated.py Normal file
View file

@ -0,0 +1,19 @@
import logging
import json
from flask import make_response
from app import app
from util.useremails import CannotSendEmailException
from data import model
logger = logging.getLogger(__name__)
@app.errorhandler(model.DataModelException)
def handle_dme(ex):
logger.exception(ex)
return make_response(json.dumps({'message': ex.message}), 400)
@app.errorhandler(CannotSendEmailException)
def handle_emailexception(ex):
message = 'Could not send email. Please contact an administrator and report this problem.'
return make_response(json.dumps({'message': message}), 400)

View file

@ -27,6 +27,9 @@ import features
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Capture the unverified SSL errors.
logging.captureWarnings(True)
web = Blueprint('web', __name__) web = Blueprint('web', __name__)
STATUS_TAGS = app.config['STATUS_TAGS'] STATUS_TAGS = app.config['STATUS_TAGS']
@ -167,7 +170,11 @@ def health():
port = ':' + hostname_parts[1] port = ':' + hostname_parts[1]
registry_url = '%s://localhost%s/v1/_internal_ping' % (app.config['PREFERRED_URL_SCHEME'], port) registry_url = '%s://localhost%s/v1/_internal_ping' % (app.config['PREFERRED_URL_SCHEME'], port)
registry_healthy = False
try:
registry_healthy = client.get(registry_url, verify=False, timeout=2).status_code == 200 registry_healthy = client.get(registry_url, verify=False, timeout=2).status_code == 200
except Exception:
logger.exception('Exception when checking registry health: %s', registry_url)
check = HealthCheck.get_check(app.config['HEALTH_CHECKER'][0], app.config['HEALTH_CHECKER'][1]) check = HealthCheck.get_check(app.config['HEALTH_CHECKER'][0], app.config['HEALTH_CHECKER'][1])
(data, is_healthy) = check.conduct_healthcheck(db_healthy, buildlogs_healthy, registry_healthy) (data, is_healthy) = check.conduct_healthcheck(db_healthy, buildlogs_healthy, registry_healthy)