Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1200)

Unified Diff: appengine/monorail/services/client_config_svc.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « appengine/monorail/services/caches.py ('k') | appengine/monorail/services/config_svc.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/monorail/services/client_config_svc.py
diff --git a/appengine/monorail/services/client_config_svc.py b/appengine/monorail/services/client_config_svc.py
new file mode 100644
index 0000000000000000000000000000000000000000..4a92cdcd0d398335274e29b873cfc6e063c4fbbe
--- /dev/null
+++ b/appengine/monorail/services/client_config_svc.py
@@ -0,0 +1,134 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is govered by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+import base64
+import json
+import logging
+import os
+import time
+import urllib
+
+from google import protobuf
+from google.appengine.api import app_identity
+from google.appengine.api import urlfetch
+
+import settings
+from framework import framework_constants
+from proto import api_clients_config_pb2
+
+
+CONFIG_FILE_PATH = os.path.join(
+ os.path.dirname(os.path.dirname(os.path.realpath(__file__))),
+ 'testing', 'api_clients.cfg')
+MONORAIL_CONFIG_SET = urllib.quote(
+ 'services/%s' % app_identity.get_application_id(), safe='')
+LUCI_CONFIG_URL = (
+ 'https://luci-config.appspot.com/_ah/api/config/v1/config_sets'
+ '/%s/config/api_clients.cfg') % MONORAIL_CONFIG_SET
+
+
+client_config_svc = None
+service_account_map = None
+
+
+class ClientConfigService(object):
+ """The persistence layer for client config data."""
+
+ # One hour
+ EXPIRES_IN = 3600
+
+ def __init__(self):
+ self.client_configs = None
+ self.load_time = 0
+
+ def GetConfigs(self, use_cache=True, cur_time=None):
+ """Read client configs."""
+
+ cur_time = cur_time or int(time.time())
+ force_load = False
+ if not self.client_configs:
+ force_load = True
+ elif not use_cache:
+ force_load = True
+ elif cur_time - self.load_time > self.EXPIRES_IN:
+ force_load = True
+
+ if force_load:
+ if settings.dev_mode or settings.unit_test_mode:
+ self._ReadFromLocal()
+ else:
+ self._ReadFromLuciConfig()
+
+ return self.client_configs
+
+ def _ReadFromLocal(self):
+ try:
+ with open(CONFIG_FILE_PATH, 'r') as f:
+ content_text = f.read()
+ logging.info('Read client configs from local file.')
+ cfg = api_clients_config_pb2.ClientCfg()
+ protobuf.text_format.Merge(content_text, cfg)
+ self.client_configs = cfg
+ self.load_time = int(time.time())
+ except Exception as ex:
+ logging.exception(
+ 'Failed to read client configs: %s',
+ str(ex))
+
+ def _ReadFromLuciConfig(self):
+ try:
+ authorization_token, _ = app_identity.get_access_token(
+ framework_constants.OAUTH_SCOPE)
+ response = urlfetch.fetch(
+ LUCI_CONFIG_URL,
+ method=urlfetch.GET,
+ follow_redirects=False,
+ headers={'Content-Type': 'application/json; charset=UTF-8',
+ 'Authorization': 'Bearer ' + authorization_token})
+ if response.status_code == 200:
+ content = json.loads(response.content)
+ config_content = content['content']
+ content_text = base64.b64decode(config_content)
+ logging.info('luci-config content decoded: %r.', content_text)
+ cfg = api_clients_config_pb2.ClientCfg()
+ protobuf.text_format.Merge(content_text, cfg)
+ self.client_configs = cfg
+ self.load_time = int(time.time())
+ else:
+ logging.error('Invalid response from luci-config: %r', response)
+ except Exception as ex:
+ logging.exception(
+ 'Failed to retrieve client configs from luci-config: %s',
+ str(ex))
+
+ def GetClientIDEmails(self):
+ """Get client IDs and Emails."""
+ self.GetConfigs(use_cache=True)
+ client_ids = [c.client_id for c in self.client_configs.clients]
+ client_emails = [c.client_email for c in self.client_configs.clients]
+ return client_ids, client_emails
+
+ def GetDisplayNames(self):
+ """Get client display names."""
+ self.GetConfigs(use_cache=True)
+ names_dict = {}
+ for client in self.client_configs.clients:
+ if client.display_name:
+ names_dict[client.client_email] = client.display_name
+ return names_dict
+
+
+def GetClientConfigSvc():
+ global client_config_svc
+ if client_config_svc is None:
+ client_config_svc = ClientConfigService()
+ return client_config_svc
+
+def GetServiceAccountMap():
+ global service_account_map
+ if service_account_map is None:
+ service_account_map = GetClientConfigSvc().GetDisplayNames()
+ return service_account_map
+
« no previous file with comments | « appengine/monorail/services/caches.py ('k') | appengine/monorail/services/config_svc.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698