def write_custom_metric(cls, call, value): """Writes a value to the audit loop custom metric. Args: call: The call the metric is for. A string like insert or delete. value: Number of milliseconds latency. Returns: An empty dictionary. """ now = utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ') body = { 'timeSeries': [{ 'metric': { 'type': AuditLogLoop.CUSTOM_METRIC_TYPE, 'labels': { 'call': call } }, 'points': [{ 'interval': { 'startTime': now, 'endTime': now }, 'value': { 'int64Value': value } }] }] } response = api.CLIENTS.metrics.projects().timeSeries().create( name='projects/' + config.get_project_id(), body=body).execute() return response
def create_custom_metric(cls): """Create Stackdriver audit log custom metric. Returns: Operation for creating the custom metric. """ body = { 'type': AuditLogLoop.CUSTOM_METRIC_TYPE, 'labels': [{ 'key': 'call', 'valueType': 'STRING', 'description': 'the API call the delay is for. (insert/delete)' }], 'metricKind': 'GAUGE', 'valueType': 'INT64', 'unit': 'msecs', 'description': 'ms delay for receiving GCE audit log events.', 'displayName': 'dns sync gce audit log delay ' } operation = api.CLIENTS.metrics.projects().metricDescriptors().create( name='projects/' + config.get_project_id(), body=body).execute() return operation
def get_custom_metric(cls): """Query for and return the Stackdriver audit loop custom metric. Returns: Dictionary representing the custom metric. """ filter_str = 'metric.type=starts_with("{}")'.format( AuditLogLoop.CUSTOM_METRIC_TYPE) descriptors = api.CLIENTS.metrics.projects().metricDescriptors().list( name='projects/' + config.get_project_id(), filter=filter_str).execute() return descriptors.get('metricDescriptors', None)
def stop_test_resource(self): """Call GCE API to stop the test resource. Returns: GCE operation. """ operation = api.CLIENTS.compute.instances().stop( instance=AuditLogLoop.RESOURCE_NAME, project=config.get_project_id(), zone=AuditLogLoop.ZONE).execute() self.record_call('stop', operation) return operation
def create_test_resource_body(self): """Creates the body of a request to create the test resource. Returns: A dictionary for supplying as the body parameter of a compute.instances.insert call. """ machine_type = ('https://www.googleapis.com/compute/v1/projects/' '{}/zones/{}/machineTypes/f1-micro').format( config.get_project_id(), AuditLogLoop.ZONE) network = ('https://www.googleapis.com/compute/v1/projects/' '{}/global/networks/default').format( config.get_project_id()) image = ('https://www.googleapis.com/compute/v1/projects/' 'ubuntu-os-cloud/global/images/family/ubuntu-1604-lts') body = { 'zone': AuditLogLoop.ZONE, 'machineType': machine_type, 'name': AuditLogLoop.RESOURCE_NAME, 'networkInterfaces': [{ 'network': network }], 'disks': [{ 'type': 'PERSISTENT', 'boot': True, 'autoDelete': True, 'initializeParams': { 'sourceImage': image } }] } return body
def is_admin(self, credentials): """Check if user has appengine.admin role. Calls iam.projects.testIamPermissions with appengine.applications.update to determine if the current logged in user is an application admin. Args: credentials: the user's access token. Returns: True if user is an admin, False otherwise. """ admin_permission = 'appengine.applications.update' body = {'permissions': admin_permission} http = credentials.authorize(httplib2.Http()) response = api.CLIENTS.iam.projects().testIamPermissions( resource=config.get_project_id(), body=body).execute(http=http) return admin_permission in response.get('permissions', [])
def get_test_resource(cls): """Return the GCE Instance the audit loop uses. Returns: Dictionary representing the GCE instance, None if not found. Raises: errors.HttpError: On a failed API call. """ try: resource = api.CLIENTS.compute.instances().get( instance=AuditLogLoop.RESOURCE_NAME, project=config.get_project_id(), zone=AuditLogLoop.ZONE).execute() except errors.HttpError as e: if e.resp.status == 404: return None else: raise return resource
def delete_test_resource(self): """Call GCE API to delete the test resource. Returns: GCE operation. Raises: errors.HttpError: On a failed API call. """ request = api.CLIENTS.compute.instances().delete( instance=AuditLogLoop.RESOURCE_NAME, project=config.get_project_id(), zone=AuditLogLoop.ZONE) try: operation = request.execute() except errors.HttpError as e: if e.resp.status == 404: logging.warning('test resource does not exist') return None else: raise self.record_call('delete', operation) return operation
def insert_test_resource(self): """Call GCE API to create the test resource. Returns: GCE operation. Raises: errors.HttpError: On a failed API call. """ body = self.create_test_resource_body() try: request = api.CLIENTS.compute.instances().insert( project=config.get_project_id(), zone=AuditLogLoop.ZONE, body=body) operation = request.execute() except errors.HttpError as e: if e.resp.status == 409: logging.warning('test resource already exists') return None else: raise self.record_call('insert', operation) return operation
def managed_zone_project(self): """Return project owning all Cloud DNS zones.""" return self.config.get('dns_project', None) or get_project_id()
def managed_zone_project(self): """Returns either the DNS project, or the current project.""" return (self.get('dns_project', None) or get_project_id())
# limitations under the License. import logging import urllib import uuid from google.cloud import datastore import httplib2 from oauth2client import client from webapp2_extras import securecookie import webapp2 from dns_sync import api from dns_sync import config COOKIE_SIGNER = securecookie.SecureCookieSerializer(config.get_project_id()) COOKIE_MAX_AGE_SECS = 60 * 60 class UserOauth2Token(datastore.Entity): """Stores user access tokens in the datastore. These tokens are deleted when users signs out or a 401 (invalid auth) is returned from the API. The Key is a random string which is also the cookie value. """ KIND = 'UserOauth2Token' def __init__(self, entity_id, credentials, is_admin=False): super(UserOauth2Token, self).__init__(key=api.CLIENTS.datastore.key(