From 15c15faf306c61251a4d9082d83345d2ff8220d9 Mon Sep 17 00:00:00 2001 From: Sam Chow Date: Mon, 14 May 2018 13:12:42 -0400 Subject: [PATCH] Return template from call --- config_app/app.py | 254 ----------------------- config_app/application.py | 8 +- config_app/config_endpoints/common.py | 78 +++++++ config_app/config_endpoints/setup_web.py | 21 +- config_app/templates/config_index.html | 23 +- 5 files changed, 105 insertions(+), 279 deletions(-) create mode 100644 config_app/config_endpoints/common.py diff --git a/config_app/app.py b/config_app/app.py index 90f5771b6..ba09f5713 100644 --- a/config_app/app.py +++ b/config_app/app.py @@ -1,257 +1,3 @@ -import hashlib -import json -import logging -import os - -from functools import partial - -from Crypto.PublicKey import RSA from flask import Flask, request, Request -from flask_login import LoginManager -from flask_mail import Mail -from flask_principal import Principal -from jwkest.jwk import RSAKey - -import features -from _init import CONF_DIR -from auth.auth_context import get_authenticated_user -from avatars.avatars import Avatar -from buildman.manager.buildcanceller import BuildCanceller -from data import database -from data import model -from data.archivedlogs import LogArchive -from data.billing import Billing -from data.buildlogs import BuildLogs -from data.cache import get_model_cache -from data.model.user import LoginWrappedDBUser -from data.queue import WorkQueue, BuildMetricQueueReporter -from data.userevent import UserEventsBuilderModule -from data.userfiles import Userfiles -from data.users import UserAuthentication -from path_converters import RegexConverter, RepositoryPathConverter, APIRepositoryPathConverter -from oauth.services.github import GithubOAuthService -from oauth.services.gitlab import GitLabOAuthService -from oauth.loginmanager import OAuthLoginManager -from storage import Storage -from util.log import filter_logs -from util import get_app_url -from util.ipresolver import IPResolver -from util.saas.analytics import Analytics -from util.saas.useranalytics import UserAnalytics -from util.saas.exceptionlog import Sentry -from util.names import urn_generator -from util.config.configutil import generate_secret_key -from util.config.provider import get_config_provider -from util.config.superusermanager import SuperUserManager -from util.label_validator import LabelValidator -from util.metrics.metricqueue import MetricQueue -from util.metrics.prometheus import PrometheusPlugin -from util.saas.cloudwatch import start_cloudwatch_sender -from util.secscan.api import SecurityScannerAPI -from util.tufmetadata.api import TUFMetadataAPI -from util.security.instancekeys import InstanceKeys -from util.security.signing import Signer - - -OVERRIDE_CONFIG_DIRECTORY = os.path.join(CONF_DIR, 'stack/') -OVERRIDE_CONFIG_YAML_FILENAME = os.path.join(CONF_DIR, 'stack/config.yaml') -OVERRIDE_CONFIG_PY_FILENAME = os.path.join(CONF_DIR, 'stack/config.py') - -OVERRIDE_CONFIG_KEY = 'QUAY_OVERRIDE_CONFIG' - -DOCKER_V2_SIGNINGKEY_FILENAME = 'docker_v2.pem' app = Flask(__name__) -logger = logging.getLogger(__name__) - -# Instantiate the configuration. -is_testing = 'TEST' in os.environ -is_kubernetes = 'KUBERNETES_SERVICE_HOST' in os.environ -config_provider = get_config_provider(OVERRIDE_CONFIG_DIRECTORY, 'config.yaml', 'config.py', - testing=is_testing, kubernetes=is_kubernetes) - -if is_testing: - from test.testconfig import TestConfig - logger.debug('Loading test config.') - app.config.from_object(TestConfig()) -else: - from config import DefaultConfig - logger.debug('Loading default config.') - app.config.from_object(DefaultConfig()) - app.teardown_request(database.close_db_filter) - -# Load the override config via the provider. -config_provider.update_app_config(app.config) - -# Update any configuration found in the override environment variable. -environ_config = json.loads(os.environ.get(OVERRIDE_CONFIG_KEY, '{}')) -app.config.update(environ_config) - -# Allow user to define a custom storage preference for the local instance. -_distributed_storage_preference = os.environ.get('QUAY_DISTRIBUTED_STORAGE_PREFERENCE', '').split() -if _distributed_storage_preference: - app.config['DISTRIBUTED_STORAGE_PREFERENCE'] = _distributed_storage_preference - -# Generate a secret key if none was specified. -if app.config['SECRET_KEY'] is None: - logger.debug('Generating in-memory secret key') - app.config['SECRET_KEY'] = generate_secret_key() - -# If the "preferred" scheme is https, then http is not allowed. Therefore, ensure we have a secure -# session cookie. -if (app.config['PREFERRED_URL_SCHEME'] == 'https' and - not app.config.get('FORCE_NONSECURE_SESSION_COOKIE', False)): - app.config['SESSION_COOKIE_SECURE'] = True - -# Load features from config. -features.import_features(app.config) - -CONFIG_DIGEST = hashlib.sha256(json.dumps(app.config, default=str)).hexdigest()[0:8] - -logger.debug("Loaded config", extra={"config": app.config}) - - -class RequestWithId(Request): - request_gen = staticmethod(urn_generator(['request'])) - - def __init__(self, *args, **kwargs): - super(RequestWithId, self).__init__(*args, **kwargs) - self.request_id = self.request_gen() - - -@app.before_request -def _request_start(): - logger.debug('Starting request: %s (%s)', request.request_id, request.path, - extra={"request_id": request.request_id}) - - -DEFAULT_FILTER = lambda x: '[FILTERED]' -FILTERED_VALUES = [ - {'key': ['password'], 'fn': DEFAULT_FILTER}, - {'key': ['user', 'password'], 'fn': DEFAULT_FILTER}, - {'key': ['blob'], 'fn': lambda x: x[0:8]} -] - - -@app.after_request -def _request_end(resp): - jsonbody = request.get_json(force=True, silent=True) - values = request.values.to_dict() - - if jsonbody and not isinstance(jsonbody, dict): - jsonbody = {'_parsererror': jsonbody} - - if isinstance(values, dict): - filter_logs(values, FILTERED_VALUES) - - extra = { - "endpoint": request.endpoint, - "request_id" : request.request_id, - "remote_addr": request.remote_addr, - "http_method": request.method, - "original_url": request.url, - "path": request.path, - "parameters": values, - "json_body": jsonbody, - "confsha": CONFIG_DIGEST, - } - - if request.user_agent is not None: - extra["user-agent"] = request.user_agent.string - - logger.debug('Ending request: %s (%s)', request.request_id, request.path, extra=extra) - return resp - - - -root_logger = logging.getLogger() - -app.request_class = RequestWithId - -# Register custom converters. -app.url_map.converters['regex'] = RegexConverter -app.url_map.converters['repopath'] = RepositoryPathConverter -app.url_map.converters['apirepopath'] = APIRepositoryPathConverter - -Principal(app, use_sessions=False) - -tf = app.config['DB_TRANSACTION_FACTORY'] - -model_cache = get_model_cache(app.config) -avatar = Avatar(app) -login_manager = LoginManager(app) -mail = Mail(app) -prometheus = PrometheusPlugin(app) -metric_queue = MetricQueue(prometheus) -chunk_cleanup_queue = WorkQueue(app.config['CHUNK_CLEANUP_QUEUE_NAME'], tf, metric_queue=metric_queue) -instance_keys = InstanceKeys(app) -ip_resolver = IPResolver(app) -storage = Storage(app, metric_queue, chunk_cleanup_queue, instance_keys, config_provider, ip_resolver) -userfiles = Userfiles(app, storage) -log_archive = LogArchive(app, storage) -analytics = Analytics(app) -user_analytics = UserAnalytics(app) -billing = Billing(app) -sentry = Sentry(app) -build_logs = BuildLogs(app) -authentication = UserAuthentication(app, config_provider, OVERRIDE_CONFIG_DIRECTORY) -userevents = UserEventsBuilderModule(app) -superusers = SuperUserManager(app) -signer = Signer(app, config_provider) -instance_keys = InstanceKeys(app) -label_validator = LabelValidator(app) -build_canceller = BuildCanceller(app) - -start_cloudwatch_sender(metric_queue, app) - -github_trigger = GithubOAuthService(app.config, 'GITHUB_TRIGGER_CONFIG') -gitlab_trigger = GitLabOAuthService(app.config, 'GITLAB_TRIGGER_CONFIG') - -oauth_login = OAuthLoginManager(app.config) -oauth_apps = [github_trigger, gitlab_trigger] - -image_replication_queue = WorkQueue(app.config['REPLICATION_QUEUE_NAME'], tf, - has_namespace=False, metric_queue=metric_queue) -dockerfile_build_queue = WorkQueue(app.config['DOCKERFILE_BUILD_QUEUE_NAME'], tf, - metric_queue=metric_queue, - reporter=BuildMetricQueueReporter(metric_queue), - has_namespace=True) -notification_queue = WorkQueue(app.config['NOTIFICATION_QUEUE_NAME'], tf, has_namespace=True, - metric_queue=metric_queue) -secscan_notification_queue = WorkQueue(app.config['SECSCAN_NOTIFICATION_QUEUE_NAME'], tf, - has_namespace=False, - metric_queue=metric_queue) - -# Note: We set `has_namespace` to `False` here, as we explicitly want this queue to not be emptied -# when a namespace is marked for deletion. -namespace_gc_queue = WorkQueue(app.config['NAMESPACE_GC_QUEUE_NAME'], tf, has_namespace=False, - metric_queue=metric_queue) - -all_queues = [image_replication_queue, dockerfile_build_queue, notification_queue, - secscan_notification_queue, chunk_cleanup_queue, namespace_gc_queue] - -secscan_api = SecurityScannerAPI(app, app.config, storage) -tuf_metadata_api = TUFMetadataAPI(app, app.config) - -# Check for a key in config. If none found, generate a new signing key for Docker V2 manifests. -_v2_key_path = os.path.join(OVERRIDE_CONFIG_DIRECTORY, DOCKER_V2_SIGNINGKEY_FILENAME) -if os.path.exists(_v2_key_path): - docker_v2_signing_key = RSAKey().load(_v2_key_path) -else: - docker_v2_signing_key = RSAKey(key=RSA.generate(2048)) - - -database.configure(app.config) -model.config.app_config = app.config -model.config.store = storage -model.config.register_image_cleanup_callback(secscan_api.cleanup_layers) -model.config.register_repo_cleanup_callback(tuf_metadata_api.delete_metadata) - - -@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) - - -get_app_url = partial(get_app_url, app.config) diff --git a/config_app/application.py b/config_app/application.py index 86916e714..a4d231092 100644 --- a/config_app/application.py +++ b/config_app/application.py @@ -1,8 +1,8 @@ -import os -import logging -import logging.config +# import os +# import logging +# import logging.config -from util.log import logfile_path +# from util.log import logfile_path from app import app as application diff --git a/config_app/config_endpoints/common.py b/config_app/config_endpoints/common.py new file mode 100644 index 000000000..1bcdfb03d --- /dev/null +++ b/config_app/config_endpoints/common.py @@ -0,0 +1,78 @@ +from flask import make_response, render_template, request, session + +def render_page_template(name, route_data=None, **kwargs): + """ Renders the page template with the given name as the response and returns its contents. """ + # main_scripts = _list_files('build', 'js', js_bundle_name) + # + # use_cdn = app.config.get('USE_CDN', True) + # if request.args.get('use_cdn') is not None: + # use_cdn = request.args.get('use_cdn') == 'true' + # + # external_styles = get_external_css(local=not use_cdn) + # external_scripts = get_external_javascript(local=not use_cdn) + # + # # Add Stripe checkout if billing is enabled. + # if features.BILLING: + # external_scripts.append('//checkout.stripe.com/checkout.js') + # + # def get_external_login_config(): + # login_config = [] + # for login_service in oauth_login.services: + # login_config.append({ + # 'id': login_service.service_id(), + # 'title': login_service.service_name(), + # 'config': login_service.get_public_config(), + # 'icon': login_service.get_icon(), + # }) + # + # return login_config + # + # def get_oauth_config(): + # oauth_config = {} + # for oauth_app in oauth_apps: + # oauth_config[oauth_app.key_name] = oauth_app.get_public_config() + # + # return oauth_config + # + # contact_href = None + # if len(app.config.get('CONTACT_INFO', [])) == 1: + # contact_href = app.config['CONTACT_INFO'][0] + # + # version_number = '' + # if not features.BILLING: + # version_number = 'Quay %s' % __version__ + # + # scopes_set = {scope.scope: scope._asdict() for scope in scopes.app_scopes(app.config).values()} + + contents = render_template(name, + route_data=route_data, + # external_styles=external_styles, + # external_scripts=external_scripts, + # main_scripts=main_scripts, + # feature_set=features.get_features(), + # config_set=frontend_visible_config(app.config), + # oauth_set=get_oauth_config(), + # external_login_set=get_external_login_config(), + # scope_set=scopes_set, + # vuln_priority_set=PRIORITY_LEVELS, + # enterprise_logo=app.config.get('ENTERPRISE_LOGO_URL', ''), + # mixpanel_key=app.config.get('MIXPANEL_KEY', ''), + # munchkin_key=app.config.get('MARKETO_MUNCHKIN_ID', ''), + # recaptcha_key=app.config.get('RECAPTCHA_SITE_KEY', ''), + # google_tagmanager_key=app.config.get('GOOGLE_TAGMANAGER_KEY', ''), + # google_anaytics_key=app.config.get('GOOGLE_ANALYTICS_KEY', ''), + # sentry_public_dsn=app.config.get('SENTRY_PUBLIC_DSN', ''), + # is_debug=str(app.config.get('DEBUGGING', False)).lower(), + # show_chat=features.SUPPORT_CHAT, + # aci_conversion=features.ACI_CONVERSION, + # has_billing=features.BILLING, + # contact_href=contact_href, + # hostname=app.config['SERVER_HOSTNAME'], + # preferred_scheme=app.config['PREFERRED_URL_SCHEME'], + # version_number=version_number, + # current_year=datetime.datetime.now().year, + **kwargs) + + resp = make_response(contents) + resp.headers['X-FRAME-OPTIONS'] = 'DENY' + return resp diff --git a/config_app/config_endpoints/setup_web.py b/config_app/config_endpoints/setup_web.py index c819dfb1d..eb07ae01d 100644 --- a/config_app/config_endpoints/setup_web.py +++ b/config_app/config_endpoints/setup_web.py @@ -5,25 +5,26 @@ import logging from datetime import timedelta, datetime from cachetools import lru_cache -from flask import (abort, redirect, request, url_for, make_response, Response, render_template, - Blueprint, jsonify, send_file, session) -from flask_login import current_user +# from flask import (abort, redirect, request, url_for, make_response, Response, render_template, +# Blueprint, jsonify, send_file, session) +from flask import Blueprint +# from flask_login import current_user from app import (app) -from endpoints.api.discovery import swagger_route_data -from endpoints.common import common_login, render_page_template +# from endpoints.api.discovery import swagger_route_data +from common import render_page_template from util.cache import no_cache -@lru_cache(maxsize=1) -def _get_route_data(): - return swagger_route_data(include_internal=True, compact=True) +# @lru_cache(maxsize=1) +# def _get_route_data(): +# return swagger_route_data(include_internal=True, compact=True) def render_page_template_with_routedata(name, *args, **kwargs): - return render_page_template(name, _get_route_data(), *args, **kwargs) + return render_page_template(name, *args, **kwargs) # Capture the unverified SSL errors. logger = logging.getLogger(__name__) @@ -31,7 +32,7 @@ logging.captureWarnings(True) setup_web = Blueprint('setup_web', __name__, template_folder='templates') -STATUS_TAGS = app.config['STATUS_TAGS'] +# STATUS_TAGS = app.config['STATUS_TAGS'] @setup_web.route('/', methods=['GET'], defaults={'path': ''}) @no_cache diff --git a/config_app/templates/config_index.html b/config_app/templates/config_index.html index f81ae7935..234e5fb5c 100644 --- a/config_app/templates/config_index.html +++ b/config_app/templates/config_index.html @@ -1,11 +1,12 @@ -{% extends "base.html" %} - -{% block title %} - Config mode -{% endblock %} -{% block body_content %} -

-

What is my purpose?
-
You create tarballs
-

-{% endblock %} + + + + Config app + + +
+

What is my purpose

+

You make tarballs

+
+ +