Example #1
0
    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
Example #2
0
    def client(self) -> _SecretManagerClient:
        """
        Cached property returning secret client.

        :return: Secrets client
        """
        return _SecretManagerClient(credentials=self.credentials)
Example #3
0
 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)
Example #4
0
 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())
Example #5
0
 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')
Example #6
0
 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')
Example #7
0
 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')
Example #9
0
 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())