def _get_credentials_using_key_secret_name(self): self._log_debug( 'Getting connection using JSON key data from GCP secret: %s', self.key_secret_name) # Use ADC to access GCP Secret Manager. adc_credentials, adc_project_id = google.auth.default( scopes=self.scopes) secret_manager_client = _SecretManagerClient( credentials=adc_credentials) if not secret_manager_client.is_valid_secret_name( self.key_secret_name): raise AirflowException( 'Invalid secret name specified for fetching JSON key data.') secret_value = secret_manager_client.get_secret( secret_id=self.key_secret_name, project_id=self.key_secret_project_id if self.key_secret_project_id else adc_project_id, ) if secret_value is None: raise AirflowException( f"Failed getting value of secret {self.key_secret_name}.") try: keyfile_dict = json.loads(secret_value) except json.decoder.JSONDecodeError: raise AirflowException( 'Key data read from GCP Secret Manager is not valid JSON.') credentials = google.oauth2.service_account.Credentials.from_service_account_info( keyfile_dict, scopes=self.scopes) project_id = credentials.project_id return credentials, project_id
def client(self) -> _SecretManagerClient: """ Cached property returning secret client. :return: Secrets client """ return _SecretManagerClient(credentials=self.credentials)
def test_auth(self, mock_client_info, mock_secrets_client): mock_client_info_mock = mock.MagicMock() mock_client_info.return_value = mock_client_info_mock mock_secrets_client.return_value = mock.MagicMock() secrets_client = _SecretManagerClient(credentials="credentials") _ = secrets_client.client mock_client_info.assert_called_with(client_library_version='airflow_v' + version) mock_secrets_client.assert_called_with(credentials='credentials', client_info=mock_client_info_mock)
def __init__( self, gcp_conn_id: str = "google_cloud_default", delegate_to: Optional[str] = None, impersonation_chain: Optional[Union[str, Sequence[str]]] = None, ) -> None: super().__init__( gcp_conn_id=gcp_conn_id, delegate_to=delegate_to, impersonation_chain=impersonation_chain, ) self.client = _SecretManagerClient(credentials=self._get_credentials())
def test_get_no_permissions(self, mock_client_info, mock_secrets_client): mock_client = mock.MagicMock() mock_client_info.return_value = mock.MagicMock() mock_secrets_client.return_value = mock_client mock_client.secret_version_path.return_value = "full-path" # No permissions for requested secret id mock_client.access_secret_version.side_effect = PermissionDenied('test-msg') secrets_client = _SecretManagerClient(credentials="credentials") secret = secrets_client.get_secret(secret_id="missing", project_id="project_id") mock_client.secret_version_path.assert_called_once_with("project_id", 'missing', 'latest') assert secret is None mock_client.access_secret_version.assert_called_once_with('full-path')
def test_get_non_existing_key(self, mock_client_info, mock_secrets_client): mock_client = mock.MagicMock() mock_client_info.return_value = mock.MagicMock() mock_secrets_client.return_value = mock_client mock_client.secret_version_path.return_value = "full-path" # The requested secret id or secret version does not exist mock_client.access_secret_version.side_effect = NotFound('test-msg') secrets_client = _SecretManagerClient(credentials="credentials") secret = secrets_client.get_secret(secret_id="missing", project_id="project_id") mock_client.secret_version_path.assert_called_once_with("project_id", 'missing', 'latest') assert secret is None mock_client.access_secret_version.assert_called_once_with('full-path')
def test_get_existing_key(self, mock_client_info, mock_secrets_client): mock_client = mock.MagicMock() mock_client_info.return_value = mock.MagicMock() mock_secrets_client.return_value = mock_client mock_client.secret_version_path.return_value = "full-path" test_response = AccessSecretVersionResponse() test_response.payload.data = b"result" mock_client.access_secret_version.return_value = test_response secrets_client = _SecretManagerClient(credentials="credentials") secret = secrets_client.get_secret(secret_id="existing", project_id="project_id") mock_client.secret_version_path.assert_called_once_with("project_id", 'existing', 'latest') assert "result" == secret mock_client.access_secret_version.assert_called_once_with('full-path')
def test_get_existing_key_with_version(self, mock_client_info, mock_secrets_client): mock_client = mock.MagicMock() mock_client_info.return_value = mock.MagicMock() mock_secrets_client.return_value = mock_client mock_client.secret_version_path.return_value = "full-path" test_response = AccessSecretVersionResponse() test_response.payload.data = "result".encode("UTF-8") mock_client.access_secret_version.return_value = test_response secrets_client = _SecretManagerClient(credentials="credentials") secret = secrets_client.get_secret(secret_id="existing", project_id="project_id", secret_version="test-version") mock_client.secret_version_path.assert_called_once_with( "project_id", 'existing', 'test-version') self.assertEqual("result", secret) mock_client.access_secret_version.assert_called_once_with('full-path')
def __init__(self, gcp_conn_id: str = "google_cloud_default", delegate_to: Optional[str] = None) -> None: super().__init__(gcp_conn_id, delegate_to) self.client = _SecretManagerClient(credentials=self._get_credentials())