Merge branch 'master' into star
This commit is contained in:
commit
917dd6b674
229 changed files with 10807 additions and 3003 deletions
|
@ -1,32 +1,38 @@
|
|||
import logging
|
||||
|
||||
from flask import (abort, redirect, request, url_for, make_response, Response,
|
||||
Blueprint, send_from_directory, jsonify)
|
||||
Blueprint, send_from_directory, jsonify, send_file)
|
||||
|
||||
from avatar_generator import Avatar
|
||||
from flask.ext.login import current_user
|
||||
from urlparse import urlparse
|
||||
from health.healthcheck import HealthCheck
|
||||
from health.healthcheck import get_healthchecker
|
||||
|
||||
from data import model
|
||||
from data.model.oauth import DatabaseAuthorizationProvider
|
||||
from app import app, billing as stripe, build_logs, avatar
|
||||
from app import app, billing as stripe, build_logs, avatar, signer
|
||||
from auth.auth import require_session_login, process_oauth
|
||||
from auth.permissions import AdministerOrganizationPermission, ReadRepositoryPermission
|
||||
from auth.permissions import (AdministerOrganizationPermission, ReadRepositoryPermission,
|
||||
SuperUserPermission)
|
||||
|
||||
from util.invoice import renderInvoiceToPdf
|
||||
from util.seo import render_snapshot
|
||||
from util.cache import no_cache
|
||||
from endpoints.common import common_login, render_page_template, route_show_if, param_required
|
||||
from endpoints.csrf import csrf_protect, generate_csrf_token
|
||||
from endpoints.csrf import csrf_protect, generate_csrf_token, verify_csrf
|
||||
from endpoints.registry import set_cache_headers
|
||||
from util.names import parse_repository_name
|
||||
from util.names import parse_repository_name, parse_repository_name_and_tag
|
||||
from util.useremails import send_email_changed
|
||||
from util.systemlogs import build_logs_archive
|
||||
from auth import scopes
|
||||
|
||||
import features
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Capture the unverified SSL errors.
|
||||
logging.captureWarnings(True)
|
||||
|
||||
web = Blueprint('web', __name__)
|
||||
|
||||
STATUS_TAGS = app.config['STATUS_TAGS']
|
||||
|
@ -57,6 +63,14 @@ def snapshot(path = ''):
|
|||
abort(404)
|
||||
|
||||
|
||||
@web.route('/aci-signing-key')
|
||||
@no_cache
|
||||
def aci_signing_key():
|
||||
if not signer.name:
|
||||
abort(404)
|
||||
|
||||
return send_file(signer.public_key_path)
|
||||
|
||||
@web.route('/plans/')
|
||||
@no_cache
|
||||
@route_show_if(features.BILLING)
|
||||
|
@ -95,6 +109,7 @@ def organizations():
|
|||
def user():
|
||||
return index('')
|
||||
|
||||
|
||||
@web.route('/superuser/')
|
||||
@no_cache
|
||||
@route_show_if(features.SUPER_USERS)
|
||||
|
@ -102,6 +117,13 @@ def superuser():
|
|||
return index('')
|
||||
|
||||
|
||||
@web.route('/setup/')
|
||||
@no_cache
|
||||
@route_show_if(features.SUPER_USERS)
|
||||
def setup():
|
||||
return index('')
|
||||
|
||||
|
||||
@web.route('/signin/')
|
||||
@no_cache
|
||||
def signin(redirect=None):
|
||||
|
@ -158,33 +180,27 @@ def v1():
|
|||
return index('')
|
||||
|
||||
|
||||
# TODO(jschorr): Remove this mirrored endpoint once we migrate ELB.
|
||||
@web.route('/health', methods=['GET'])
|
||||
@web.route('/health/instance', methods=['GET'])
|
||||
@no_cache
|
||||
def health():
|
||||
db_healthy = model.check_health()
|
||||
buildlogs_healthy = build_logs.check_health()
|
||||
|
||||
check = HealthCheck.get_check(app.config['HEALTH_CHECKER'][0], app.config['HEALTH_CHECKER'][1])
|
||||
(data, is_healthy) = check.conduct_healthcheck(db_healthy, buildlogs_healthy)
|
||||
|
||||
response = jsonify(dict(data = data, is_healthy = is_healthy))
|
||||
response.status_code = 200 if is_healthy else 503
|
||||
def instance_health():
|
||||
checker = get_healthchecker(app)
|
||||
(data, status_code) = checker.check_instance()
|
||||
response = jsonify(dict(data=data, status_code=status_code))
|
||||
response.status_code = status_code
|
||||
return response
|
||||
|
||||
|
||||
# TODO(jschorr): Remove this mirrored endpoint once we migrate pingdom.
|
||||
@web.route('/status', methods=['GET'])
|
||||
@web.route('/health/endtoend', methods=['GET'])
|
||||
@no_cache
|
||||
def status():
|
||||
db_healthy = model.check_health()
|
||||
buildlogs_healthy = build_logs.check_health()
|
||||
|
||||
response = jsonify({
|
||||
'db_healthy': db_healthy,
|
||||
'buildlogs_healthy': buildlogs_healthy,
|
||||
'is_testing': app.config['TESTING'],
|
||||
})
|
||||
response.status_code = 200 if db_healthy and buildlogs_healthy else 503
|
||||
|
||||
def endtoend_health():
|
||||
checker = get_healthchecker(app)
|
||||
(data, status_code) = checker.check_endtoend()
|
||||
response = jsonify(dict(data=data, status_code=status_code))
|
||||
response.status_code = status_code
|
||||
return response
|
||||
|
||||
|
||||
|
@ -229,14 +245,14 @@ def robots():
|
|||
@web.route('/<path:repository>')
|
||||
@no_cache
|
||||
@process_oauth
|
||||
@parse_repository_name
|
||||
def redirect_to_repository(namespace, reponame):
|
||||
@parse_repository_name_and_tag
|
||||
def redirect_to_repository(namespace, reponame, tag):
|
||||
permission = ReadRepositoryPermission(namespace, reponame)
|
||||
is_public = model.repository_is_public(namespace, reponame)
|
||||
|
||||
if permission.can() or is_public:
|
||||
repository_name = '/'.join([namespace, reponame])
|
||||
return redirect(url_for('web.repository', path=repository_name))
|
||||
return redirect(url_for('web.repository', path=repository_name, tag=tag))
|
||||
|
||||
abort(404)
|
||||
|
||||
|
@ -471,3 +487,21 @@ def exchange_code_for_token():
|
|||
|
||||
provider = FlaskAuthorizationProvider()
|
||||
return provider.get_token(grant_type, client_id, client_secret, redirect_uri, code, scope=scope)
|
||||
|
||||
|
||||
@web.route('/systemlogsarchive', methods=['GET'])
|
||||
@process_oauth
|
||||
@route_show_if(features.SUPER_USERS)
|
||||
@no_cache
|
||||
def download_logs_archive():
|
||||
# Note: We cannot use the decorator here because this is a GET method. That being said, this
|
||||
# information is sensitive enough that we want the extra protection.
|
||||
verify_csrf()
|
||||
|
||||
if SuperUserPermission().can():
|
||||
archive_data = build_logs_archive(app)
|
||||
return Response(archive_data,
|
||||
mimetype="application/octet-stream",
|
||||
headers={"Content-Disposition": "attachment;filename=erlogs.tar.gz"})
|
||||
|
||||
abort(403)
|
||||
|
|
Reference in a new issue