Index: third_party/google-endpoints/google/api/config/service_config.py |
diff --git a/third_party/google-endpoints/google/api/config/service_config.py b/third_party/google-endpoints/google/api/config/service_config.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a26178088398d73ff316b4ea15a3fa6ea4e75b27 |
--- /dev/null |
+++ b/third_party/google-endpoints/google/api/config/service_config.py |
@@ -0,0 +1,126 @@ |
+# Copyright 2016 Google Inc. All Rights Reserved. |
+# |
+# Licensed under the Apache License, Version 2.0 (the "License"); |
+# you may not use this file except in compliance with the License. |
+# You may obtain a copy of the License at |
+# |
+# http://www.apache.org/licenses/LICENSE-2.0 |
+# |
+# Unless required by applicable law or agreed to in writing, software |
+# distributed under the License is distributed on an "AS IS" BASIS, |
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+# See the License for the specific language governing permissions and |
+# limitations under the License. |
+ |
+"""Provides a method for fetching Service Configuration from Google Service |
+Management API.""" |
+ |
+ |
+import logging |
+import json |
+import os |
+import urllib3 |
+ |
+from apitools.base.py import encoding |
+import google.api.gen.servicecontrol_v1_messages as messages |
+from oauth2client import client |
+from urllib3.contrib import appengine |
+ |
+ |
+logger = logging.getLogger(__name__) |
+ |
+_GOOGLE_API_SCOPE = "https://www.googleapis.com/auth/cloud-platform" |
+ |
+_SERVICE_MGMT_URL_TEMPLATE = ("https://servicemanagement.googleapis.com" |
+ "/v1/services/{}/configs/{}") |
+ |
+_SERVICE_NAME_ENV_KEY = "ENDPOINTS_SERVICE_NAME" |
+_SERVICE_VERSION_ENV_KEY = "ENDPOINTS_SERVICE_VERSION" |
+ |
+ |
+def fetch_service_config(service_name=None, service_version=None): |
+ """Fetches the service config from Google Serivce Management API. |
+ |
+ Args: |
+ service_name: the service name. When this argument is unspecified, this |
+ method uses the value of the "SERVICE_NAME" environment variable as the |
+ service name, and raises ValueError if the environment variable is unset. |
+ service_version: the service version. When this argument is unspecified, |
+ this method uses the value of the "SERVICE_VERSION" environment variable |
+ as the service version, and raises ValueError if the environment variable |
+ is unset. |
+ |
+ Returns: the fetched service config JSON object. |
+ |
+ Raises: |
+ ValueError: when the service name/version is neither provided as an |
+ argument or set as an environment variable; or when the fetched service |
+ config fails validation. |
+ Exception: when the Google Service Management API returns non-200 response. |
+ """ |
+ if not service_name: |
+ service_name = _get_env_var_or_raise(_SERVICE_NAME_ENV_KEY) |
+ if not service_version: |
+ service_version = _get_env_var_or_raise(_SERVICE_VERSION_ENV_KEY) |
+ |
+ service_mgmt_url = _SERVICE_MGMT_URL_TEMPLATE.format(service_name, |
+ service_version) |
+ |
+ access_token = _get_access_token() |
+ headers = {"Authorization": "Bearer {}".format(access_token)} |
+ |
+ http_client = _get_http_client() |
+ response = http_client.request("GET", service_mgmt_url, headers=headers) |
+ |
+ status_code = response.status |
+ if status_code != 200: |
+ message_template = "Fetching service config failed (status code {})" |
+ _log_and_raise(Exception, message_template.format(status_code)) |
+ |
+ logger.debug('obtained service json from the management api:\n%s', response.data) |
+ service = encoding.JsonToMessage(messages.Service, response.data) |
+ _validate_service_config(service, service_name, service_version) |
+ return service |
+ |
+ |
+def _get_access_token(): |
+ credentials = client.GoogleCredentials.get_application_default() |
+ if credentials.create_scoped_required(): |
+ credentials = credentials.create_scoped(_GOOGLE_API_SCOPE) |
+ return credentials.get_access_token().access_token |
+ |
+ |
+def _get_http_client(): |
+ if appengine.is_appengine_sandbox(): |
+ return appengine.AppEngineManager() |
+ else: |
+ return urllib3.PoolManager() |
+ |
+ |
+def _get_env_var_or_raise(env_variable_name): |
+ if env_variable_name not in os.environ: |
+ message_template = 'The "{}" environment variable is not set' |
+ _log_and_raise(ValueError, message_template.format(env_variable_name)) |
+ return os.environ[env_variable_name] |
+ |
+ |
+def _validate_service_config(service, expected_service_name, |
+ expected_service_version): |
+ service_name = service.name |
+ if not service_name: |
+ _log_and_raise(ValueError, "No service name in the service config") |
+ if service_name != expected_service_name: |
+ message_template = "Unexpected service name in service config: {}" |
+ _log_and_raise(ValueError, message_template.format(service_name)) |
+ |
+ service_version = service.id |
+ if not service_version: |
+ _log_and_raise(ValueError, "No service version in the service config") |
+ if service_version != expected_service_version: |
+ message_template = "Unexpected service version in service config: {}" |
+ _log_and_raise(ValueError, message_template.format(service_version)) |
+ |
+ |
+def _log_and_raise(exception_class, message): |
+ logger.error(message) |
+ raise exception_class(message) |