def test_service_account_email(self, get_email): credentials = AppAssertionCredentials([]) self.assertIsNone(credentials._service_account_email) self.assertEqual(credentials.service_account_email, get_email.return_value[1]) self.assertIsNotNone(credentials._service_account_email) get_email.assert_called_once_with()
def test_constructor(self): scope = 'http://example.com/a http://example.com/b' scopes = scope.split() credentials = AppAssertionCredentials(scope=scopes, foo='bar') self.assertEqual(credentials.scope, scope) self.assertEqual(credentials.kwargs, {'foo': 'bar'}) self.assertEqual(credentials.assertion_type, None)
def test_create_scoped(self, warn_mock): credentials = AppAssertionCredentials() new_credentials = credentials.create_scoped(['dummy_scope']) self.assertNotEqual(credentials, new_credentials) self.assertTrue(isinstance(new_credentials, AppAssertionCredentials)) self.assertEqual('dummy_scope', new_credentials.scope) warn_mock.assert_called_once_with(_SCOPES_WARNING)
def test_to_json_and_from_json(self): credentials = AppAssertionCredentials( scope=['http://example.com/a', 'http://example.com/b']) json = credentials.to_json() credentials_from_json = Credentials.new_from_json(json) self.assertEqual(credentials.access_token, credentials_from_json.access_token)
def test_constructor_with_scopes(self, warn_mock): scope = 'http://example.com/a http://example.com/b' scopes = scope.split() credentials = AppAssertionCredentials(scope=scopes, foo='bar') self.assertEqual(credentials.scope, scope) self.assertEqual(credentials.kwargs, {'foo': 'bar'}) self.assertEqual(credentials.assertion_type, None) warn_mock.assert_called_once_with(_SCOPES_WARNING)
def test_refresh_failure_bad_json(self): http = mock.MagicMock() content = '{BADJSON' http.request = mock.MagicMock(return_value=(mock.Mock( status=http_client.OK), content)) credentials = AppAssertionCredentials() self.assertRaises(AccessTokenRefreshError, credentials.refresh, http)
def test_save_to_well_known_file(self): import os ORIGINAL_ISDIR = os.path.isdir try: os.path.isdir = lambda path: True credentials = AppAssertionCredentials([]) self.assertRaises(NotImplementedError, save_to_well_known_file, credentials) finally: os.path.isdir = ORIGINAL_ISDIR
def EnableGceAuth(self): """Selects to use local metadata service for authentication. The project ID and project number are also retrieved from the metadata service. It is done lazily from the worker thread. The motivation is to speed up initialization and be able to recover from failures. """ self._credentials = AppAssertionCredentials() self._project_id = lambda: self._QueryGcpProject('project-id') self._project_number = lambda: self._QueryGcpProject('numeric-project-id')
def main(): config.load_incluster_config() crds = client.CustomObjectsApi() creds = AppAssertionCredentials() cloudbuild = discovery_build('cloudbuild', 'v1', credentials=creds) def watch_until_done(obj, operation): name = operation["name"] while not operation.get("done", False): logging.error("Waiting on: %s", name) time.sleep(1) operation = cloudbuild.operations().get(name=name).execute() logging.error("Complete: %s", name) spec = obj["spec"] spec["Status"] = "DONE" if "error" in operation: spec["error"] = operation["error"] else: spec["response"] = operation["response"] crds.replace_namespaced_custom_object(DOMAIN, "v1", obj["metadata"]["namespace"], "builds", obj["metadata"]["name"], obj) def build(obj): spec = obj["spec"] if "Operation" in spec: return operation = cloudbuild.projects().builds().create( projectId='convoy-adapter', body=spec).execute() spec["Operation"] = operation["name"] obj = crds.replace_namespaced_custom_object( DOMAIN, "v1", obj["metadata"]["namespace"], "builds", obj["metadata"]["name"], obj) logging.error("Waiting until %s is done", operation["name"]) watch_until_done(obj, operation) # TODO(mattmoor): On startup we should start a thread to watch any in-progress builds. stream = watch.Watch().stream(crds.list_cluster_custom_object, DOMAIN, "v1", "builds") for event in stream: # TODO(mattmoor): Execute in a threadpool. try: build(event["object"]) except: logging.exception("Error handling event")
def test_get_access_token(self): http = mock.MagicMock() http.request = mock.MagicMock(return_value=(mock.Mock( status=http_client.OK), '{"access_token": "this-is-a-token"}')) credentials = AppAssertionCredentials() token = credentials.get_access_token(http=http) self.assertEqual('this-is-a-token', token.access_token) self.assertEqual(None, token.expires_in) http.request.assert_called_once_with( 'http://metadata.google.internal/computeMetadata/v1/instance/' 'service-accounts/default/token', headers={'Metadata-Flavor': 'Google'})
def test_get_access_token(self): http = mock.MagicMock() http.request = mock.MagicMock( return_value=(mock.Mock(status=http_client.OK), '{"accessToken": "this-is-a-token"}')) credentials = AppAssertionCredentials(['dummy_scope']) token = credentials.get_access_token(http=http) self.assertEqual('this-is-a-token', token.access_token) self.assertEqual(None, token.expires_in) http.request.assert_called_once_with( 'http://metadata.google.internal/0.1/meta-data/service-accounts/' 'default/acquire?scope=dummy_scope')
def test_refresh_failure_400(self): http = mock.MagicMock() content = '{}' http.request = mock.MagicMock(return_value=(mock.Mock( status=http_client.BAD_REQUEST), content)) credentials = AppAssertionCredentials() exception_caught = None try: credentials.refresh(http) except AccessTokenRefreshError as exc: exception_caught = exc self.assertNotEqual(exception_caught, None) self.assertEqual(str(exception_caught), content)
def test_refresh_failure_404(self): http = mock.MagicMock() content = '{}' http.request = mock.MagicMock(return_value=(mock.Mock( status=http_client.NOT_FOUND), content)) credentials = AppAssertionCredentials() exception_caught = None try: credentials.refresh(http) except AccessTokenRefreshError as exc: exception_caught = exc self.assertNotEqual(exception_caught, None) expanded_content = content + (' This can occur if a VM was created' ' with no service account or scopes.') self.assertEqual(str(exception_caught), expanded_content)
def test_service_account_email_failure(self, get_email): # Set-up the mock. bad_response = httplib2.Response({'status': http_client.NOT_FOUND}) content = b'bad-bytes-nothing-here' get_email.return_value = (bad_response, content) # Test the failure. credentials = AppAssertionCredentials([]) self.assertIsNone(credentials._service_account_email) with self.assertRaises(AttributeError) as exc_manager: getattr(credentials, 'service_account_email') error_msg = ('Failed to retrieve the email from the ' 'Google Compute Engine metadata service') self.assertEqual(exc_manager.exception.args, (error_msg, bad_response, content)) self.assertIsNone(credentials._service_account_email) get_email.assert_called_once_with()
def _refresh_success_helper(self, bytes_response=False): access_token = u'this-is-a-token' return_val = json.dumps({u'access_token': access_token}) if bytes_response: return_val = _to_bytes(return_val) http = mock.MagicMock() http.request = mock.MagicMock(return_value=(mock.Mock( status=http_client.OK), return_val)) credentials = AppAssertionCredentials() self.assertEquals(None, credentials.access_token) credentials.refresh(http) self.assertEquals(access_token, credentials.access_token) base_metadata_uri = ( 'http://metadata.google.internal/computeMetadata/v1/instance/' 'service-accounts/default/token') http.request.assert_called_once_with( base_metadata_uri, headers={'Metadata-Flavor': 'Google'})
def _refresh_success_helper(self, bytes_response=False): access_token = u'this-is-a-token' return_val = json.dumps({u'accessToken': access_token}) if bytes_response: return_val = _to_bytes(return_val) http = mock.MagicMock() http.request = mock.MagicMock( return_value=(mock.Mock(status=http_client.OK), return_val)) scopes = ['http://example.com/a', 'http://example.com/b'] credentials = AppAssertionCredentials(scope=scopes) self.assertEquals(None, credentials.access_token) credentials.refresh(http) self.assertEquals(access_token, credentials.access_token) base_metadata_uri = ('http://metadata.google.internal/0.1/meta-data/' 'service-accounts/default/acquire') escaped_scopes = urllib.parse.quote(' '.join(scopes), safe='') request_uri = base_metadata_uri + '?scope=' + escaped_scopes http.request.assert_called_once_with(request_uri)
def test_token_info(self): credentials = AppAssertionCredentials([]) http = httplib2.Http() # First refresh to get the access token. self.assertIsNone(credentials.access_token) credentials.refresh(http) self.assertIsNotNone(credentials.access_token) # Then check the access token against the token info API. query_params = {'access_token': credentials.access_token} token_uri = (GOOGLE_TOKEN_INFO_URI + '?' + urllib.parse.urlencode(query_params)) response, content = http.request(token_uri) self.assertEqual(response.status, http_client.OK) content = content.decode('utf-8') payload = json.loads(content) self.assertEqual(payload['access_type'], 'offline') self.assertLessEqual(int(payload['expires_in']), 3600)
def main(): config.load_incluster_config() crds = client.CustomObjectsApi() # TODO(mattmoor): Share a library with the meta controller name = os.environ["API_NAME"] domain = "%s.googleapis.com" % name version = os.environ["API_VERSION"] resource = os.environ["API_RESOURCE"] plural = resource.lower() + "s" creds = AppAssertionCredentials() api = discovery_build(name, version, credentials=creds) def call(obj): spec = obj["spec"] logging.error("TODO call %s/%s %s on %s", name, version, resource, json.dumps(obj, indent=1)) resource_version = "" while True: stream = watch.Watch().stream(crds.list_cluster_custom_object, domain, version, plural, resource_version=resource_version) for event in stream: # TODO(mattmoor): Execute in a threadpool. try: obj = event["object"] call(obj) # Configure where to resume streaming. metadata = obj.get("metadata") if metadata: resource_version = metadata["resourceVersion"] except: logging.exception("Error handling event")
def test_create_scoped_required_with_scopes(self, warn_mock): credentials = AppAssertionCredentials(['dummy_scope']) self.assertFalse(credentials.create_scoped_required()) warn_mock.assert_called_once_with(_SCOPES_WARNING)
def test_sign_blob_not_implemented(self): credentials = AppAssertionCredentials([]) with self.assertRaises(NotImplementedError): credentials.sign_blob(b'blob')
def test_service_account_email_already_set(self, get_email): credentials = AppAssertionCredentials([]) acct_name = '*****@*****.**' credentials._service_account_email = acct_name self.assertEqual(credentials.service_account_email, acct_name) get_email.assert_not_called()
def test_create_scoped(self): credentials = AppAssertionCredentials([]) new_credentials = credentials.create_scoped(['dummy_scope']) self.assertNotEqual(credentials, new_credentials) self.assertTrue(isinstance(new_credentials, AppAssertionCredentials)) self.assertEqual('dummy_scope', new_credentials.scope)
def test_create_scoped_required_with_scopes(self): credentials = AppAssertionCredentials(['dummy_scope']) self.assertFalse(credentials.create_scoped_required())
def test_create_scoped_required_without_scopes(self): credentials = AppAssertionCredentials([]) self.assertTrue(credentials.create_scoped_required())
def test_serialization_data(self): credentials = AppAssertionCredentials(scope=[]) self.assertRaises(NotImplementedError, getattr, credentials, 'serialization_data')
def test_constructor(self): credentials = AppAssertionCredentials(foo='bar') self.assertEqual(credentials.scope, '') self.assertEqual(credentials.kwargs, {'foo': 'bar'}) self.assertEqual(credentials.assertion_type, None)
#!/usr/bin/env python from google.cloud import monitoring ''' # Using a service account with credentials in a json file: JSON_CREDS = '/path/to/json' from oauth2client.service_account import ServiceAccountCredentials scopes = ["https://www.googleapis.com/auth/monitoring",] credentials = ServiceAccountCredentials.from_json_keyfile_name( JSON_CREDS, scopes) ''' # From inside a GCE instance, with default account: from oauth2client.contrib.gce import AppAssertionCredentials credentials = AppAssertionCredentials([]) # 'project' is project ID, not name myproject = 'main-shade-732' client = monitoring.Client(project=myproject, credentials=credentials) # Delete ALL custom metrics from this project. all = client.list_metric_descriptors(type_prefix='custom.') for a in all: descriptor = client.metric_descriptor(str(a.type)) descriptor.delete()
def test_to_json_and_from_json(self): credentials = AppAssertionCredentials() json = credentials.to_json() credentials_from_json = Credentials.new_from_json(json) self.assertEqual(credentials.access_token, credentials_from_json.access_token)