apache-airflow-providers-google 10.17.0rc1__py3-none-any.whl → 10.18.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airflow/providers/google/__init__.py +3 -3
- airflow/providers/google/cloud/hooks/automl.py +1 -1
- airflow/providers/google/cloud/hooks/bigquery.py +64 -33
- airflow/providers/google/cloud/hooks/cloud_composer.py +250 -2
- airflow/providers/google/cloud/hooks/cloud_sql.py +154 -7
- airflow/providers/google/cloud/hooks/cloud_storage_transfer_service.py +7 -2
- airflow/providers/google/cloud/hooks/compute_ssh.py +2 -1
- airflow/providers/google/cloud/hooks/dataflow.py +246 -32
- airflow/providers/google/cloud/hooks/dataplex.py +6 -2
- airflow/providers/google/cloud/hooks/dlp.py +14 -14
- airflow/providers/google/cloud/hooks/gcs.py +6 -2
- airflow/providers/google/cloud/hooks/gdm.py +2 -2
- airflow/providers/google/cloud/hooks/kubernetes_engine.py +2 -2
- airflow/providers/google/cloud/hooks/mlengine.py +8 -4
- airflow/providers/google/cloud/hooks/pubsub.py +1 -1
- airflow/providers/google/cloud/hooks/secret_manager.py +252 -4
- airflow/providers/google/cloud/hooks/vertex_ai/custom_job.py +1431 -74
- airflow/providers/google/cloud/links/vertex_ai.py +2 -1
- airflow/providers/google/cloud/log/gcs_task_handler.py +2 -1
- airflow/providers/google/cloud/operators/automl.py +13 -12
- airflow/providers/google/cloud/operators/bigquery.py +36 -22
- airflow/providers/google/cloud/operators/bigquery_dts.py +4 -3
- airflow/providers/google/cloud/operators/bigtable.py +7 -6
- airflow/providers/google/cloud/operators/cloud_build.py +12 -11
- airflow/providers/google/cloud/operators/cloud_composer.py +147 -2
- airflow/providers/google/cloud/operators/cloud_memorystore.py +17 -16
- airflow/providers/google/cloud/operators/cloud_sql.py +60 -17
- airflow/providers/google/cloud/operators/cloud_storage_transfer_service.py +35 -16
- airflow/providers/google/cloud/operators/compute.py +12 -11
- airflow/providers/google/cloud/operators/datacatalog.py +21 -20
- airflow/providers/google/cloud/operators/dataflow.py +59 -42
- airflow/providers/google/cloud/operators/datafusion.py +11 -10
- airflow/providers/google/cloud/operators/datapipeline.py +3 -2
- airflow/providers/google/cloud/operators/dataprep.py +5 -4
- airflow/providers/google/cloud/operators/dataproc.py +19 -16
- airflow/providers/google/cloud/operators/datastore.py +8 -7
- airflow/providers/google/cloud/operators/dlp.py +31 -30
- airflow/providers/google/cloud/operators/functions.py +4 -3
- airflow/providers/google/cloud/operators/gcs.py +66 -41
- airflow/providers/google/cloud/operators/kubernetes_engine.py +232 -12
- airflow/providers/google/cloud/operators/life_sciences.py +2 -1
- airflow/providers/google/cloud/operators/mlengine.py +11 -10
- airflow/providers/google/cloud/operators/pubsub.py +6 -5
- airflow/providers/google/cloud/operators/spanner.py +7 -6
- airflow/providers/google/cloud/operators/speech_to_text.py +2 -1
- airflow/providers/google/cloud/operators/stackdriver.py +11 -10
- airflow/providers/google/cloud/operators/tasks.py +14 -13
- airflow/providers/google/cloud/operators/text_to_speech.py +2 -1
- airflow/providers/google/cloud/operators/translate_speech.py +2 -1
- airflow/providers/google/cloud/operators/vertex_ai/custom_job.py +333 -26
- airflow/providers/google/cloud/operators/vertex_ai/generative_model.py +20 -12
- airflow/providers/google/cloud/operators/vertex_ai/pipeline_job.py +0 -1
- airflow/providers/google/cloud/operators/vision.py +13 -12
- airflow/providers/google/cloud/operators/workflows.py +10 -9
- airflow/providers/google/cloud/secrets/secret_manager.py +2 -1
- airflow/providers/google/cloud/sensors/bigquery_dts.py +2 -1
- airflow/providers/google/cloud/sensors/bigtable.py +2 -1
- airflow/providers/google/cloud/sensors/cloud_storage_transfer_service.py +2 -1
- airflow/providers/google/cloud/sensors/dataflow.py +239 -52
- airflow/providers/google/cloud/sensors/datafusion.py +2 -1
- airflow/providers/google/cloud/sensors/dataproc.py +3 -2
- airflow/providers/google/cloud/sensors/gcs.py +14 -12
- airflow/providers/google/cloud/sensors/tasks.py +2 -1
- airflow/providers/google/cloud/sensors/workflows.py +2 -1
- airflow/providers/google/cloud/transfers/adls_to_gcs.py +8 -2
- airflow/providers/google/cloud/transfers/azure_blob_to_gcs.py +7 -1
- airflow/providers/google/cloud/transfers/azure_fileshare_to_gcs.py +7 -1
- airflow/providers/google/cloud/transfers/bigquery_to_gcs.py +2 -1
- airflow/providers/google/cloud/transfers/bigquery_to_mssql.py +1 -1
- airflow/providers/google/cloud/transfers/bigquery_to_sql.py +1 -0
- airflow/providers/google/cloud/transfers/gcs_to_bigquery.py +5 -6
- airflow/providers/google/cloud/transfers/gcs_to_gcs.py +22 -12
- airflow/providers/google/cloud/triggers/bigquery.py +14 -3
- airflow/providers/google/cloud/triggers/cloud_composer.py +68 -0
- airflow/providers/google/cloud/triggers/cloud_sql.py +2 -1
- airflow/providers/google/cloud/triggers/cloud_storage_transfer_service.py +2 -1
- airflow/providers/google/cloud/triggers/dataflow.py +504 -4
- airflow/providers/google/cloud/triggers/dataproc.py +110 -26
- airflow/providers/google/cloud/triggers/mlengine.py +2 -1
- airflow/providers/google/cloud/triggers/vertex_ai.py +94 -0
- airflow/providers/google/common/hooks/base_google.py +45 -7
- airflow/providers/google/firebase/hooks/firestore.py +2 -2
- airflow/providers/google/firebase/operators/firestore.py +2 -1
- airflow/providers/google/get_provider_info.py +3 -2
- {apache_airflow_providers_google-10.17.0rc1.dist-info → apache_airflow_providers_google-10.18.0rc1.dist-info}/METADATA +8 -8
- {apache_airflow_providers_google-10.17.0rc1.dist-info → apache_airflow_providers_google-10.18.0rc1.dist-info}/RECORD +88 -89
- airflow/providers/google/cloud/example_dags/example_cloud_sql_query.py +0 -289
- {apache_airflow_providers_google-10.17.0rc1.dist-info → apache_airflow_providers_google-10.18.0rc1.dist-info}/WHEEL +0 -0
- {apache_airflow_providers_google-10.17.0rc1.dist-info → apache_airflow_providers_google-10.18.0rc1.dist-info}/entry_points.txt +0 -0
@@ -36,7 +36,11 @@ from google.protobuf.field_mask_pb2 import FieldMask
|
|
36
36
|
|
37
37
|
from airflow.exceptions import AirflowException
|
38
38
|
from airflow.providers.google.common.consts import CLIENT_INFO
|
39
|
-
from airflow.providers.google.common.hooks.base_google import
|
39
|
+
from airflow.providers.google.common.hooks.base_google import (
|
40
|
+
PROVIDE_PROJECT_ID,
|
41
|
+
GoogleBaseAsyncHook,
|
42
|
+
GoogleBaseHook,
|
43
|
+
)
|
40
44
|
|
41
45
|
if TYPE_CHECKING:
|
42
46
|
from google.api_core.operation import Operation
|
@@ -665,7 +669,7 @@ class DataplexHook(GoogleBaseHook):
|
|
665
669
|
self,
|
666
670
|
data_scan_id: str,
|
667
671
|
job_id: str | None = None,
|
668
|
-
project_id: str
|
672
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
669
673
|
region: str | None = None,
|
670
674
|
wait_time: int = 10,
|
671
675
|
result_timeout: float | None = None,
|
@@ -162,7 +162,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
162
162
|
def create_deidentify_template(
|
163
163
|
self,
|
164
164
|
organization_id: str | None = None,
|
165
|
-
project_id: str
|
165
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
166
166
|
deidentify_template: dict | DeidentifyTemplate | None = None,
|
167
167
|
template_id: str | None = None,
|
168
168
|
retry: Retry | _MethodDefault = DEFAULT,
|
@@ -287,7 +287,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
287
287
|
def create_inspect_template(
|
288
288
|
self,
|
289
289
|
organization_id: str | None = None,
|
290
|
-
project_id: str
|
290
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
291
291
|
inspect_template: InspectTemplate | None = None,
|
292
292
|
template_id: str | None = None,
|
293
293
|
retry: Retry | _MethodDefault = DEFAULT,
|
@@ -376,7 +376,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
376
376
|
def create_stored_info_type(
|
377
377
|
self,
|
378
378
|
organization_id: str | None = None,
|
379
|
-
project_id: str
|
379
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
380
380
|
config: dict | StoredInfoTypeConfig | None = None,
|
381
381
|
stored_info_type_id: str | None = None,
|
382
382
|
retry: Retry | _MethodDefault = DEFAULT,
|
@@ -565,7 +565,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
565
565
|
self,
|
566
566
|
template_id: str,
|
567
567
|
organization_id: str | None = None,
|
568
|
-
project_id: str
|
568
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
569
569
|
retry: Retry | _MethodDefault = DEFAULT,
|
570
570
|
timeout: float | None = None,
|
571
571
|
metadata: Sequence[tuple[str, str]] = (),
|
@@ -652,7 +652,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
652
652
|
self,
|
653
653
|
stored_info_type_id: str,
|
654
654
|
organization_id: str | None = None,
|
655
|
-
project_id: str
|
655
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
656
656
|
retry: Retry | _MethodDefault = DEFAULT,
|
657
657
|
timeout: float | None = None,
|
658
658
|
metadata: Sequence[tuple[str, str]] = (),
|
@@ -701,7 +701,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
701
701
|
self,
|
702
702
|
template_id: str,
|
703
703
|
organization_id: str | None = None,
|
704
|
-
project_id: str
|
704
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
705
705
|
retry: Retry | _MethodDefault = DEFAULT,
|
706
706
|
timeout: float | None = None,
|
707
707
|
metadata: Sequence[tuple[str, str]] = (),
|
@@ -788,7 +788,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
788
788
|
self,
|
789
789
|
template_id: str,
|
790
790
|
organization_id: str | None = None,
|
791
|
-
project_id: str
|
791
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
792
792
|
retry: Retry | _MethodDefault = DEFAULT,
|
793
793
|
timeout: float | None = None,
|
794
794
|
metadata: Sequence[tuple[str, str]] = (),
|
@@ -875,7 +875,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
875
875
|
self,
|
876
876
|
stored_info_type_id: str,
|
877
877
|
organization_id: str | None = None,
|
878
|
-
project_id: str
|
878
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
879
879
|
retry: Retry | _MethodDefault = DEFAULT,
|
880
880
|
timeout: float | None = None,
|
881
881
|
metadata: Sequence[tuple[str, str]] = (),
|
@@ -967,7 +967,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
967
967
|
def list_deidentify_templates(
|
968
968
|
self,
|
969
969
|
organization_id: str | None = None,
|
970
|
-
project_id: str
|
970
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
971
971
|
page_size: int | None = None,
|
972
972
|
order_by: str | None = None,
|
973
973
|
retry: Retry | _MethodDefault = DEFAULT,
|
@@ -1103,7 +1103,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
1103
1103
|
def list_inspect_templates(
|
1104
1104
|
self,
|
1105
1105
|
organization_id: str | None = None,
|
1106
|
-
project_id: str
|
1106
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
1107
1107
|
page_size: int | None = None,
|
1108
1108
|
order_by: str | None = None,
|
1109
1109
|
retry: Retry | _MethodDefault = DEFAULT,
|
@@ -1201,7 +1201,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
1201
1201
|
def list_stored_info_types(
|
1202
1202
|
self,
|
1203
1203
|
organization_id: str | None = None,
|
1204
|
-
project_id: str
|
1204
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
1205
1205
|
page_size: int | None = None,
|
1206
1206
|
order_by: str | None = None,
|
1207
1207
|
retry: Retry | _MethodDefault = DEFAULT,
|
@@ -1356,7 +1356,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
1356
1356
|
self,
|
1357
1357
|
template_id: str,
|
1358
1358
|
organization_id: str | None = None,
|
1359
|
-
project_id: str
|
1359
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
1360
1360
|
deidentify_template: dict | DeidentifyTemplate | None = None,
|
1361
1361
|
update_mask: dict | FieldMask | None = None,
|
1362
1362
|
retry: Retry | _MethodDefault = DEFAULT,
|
@@ -1411,7 +1411,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
1411
1411
|
self,
|
1412
1412
|
template_id: str,
|
1413
1413
|
organization_id: str | None = None,
|
1414
|
-
project_id: str
|
1414
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
1415
1415
|
inspect_template: dict | InspectTemplate | None = None,
|
1416
1416
|
update_mask: dict | FieldMask | None = None,
|
1417
1417
|
retry: Retry | _MethodDefault = DEFAULT,
|
@@ -1513,7 +1513,7 @@ class CloudDLPHook(GoogleBaseHook):
|
|
1513
1513
|
self,
|
1514
1514
|
stored_info_type_id: str,
|
1515
1515
|
organization_id: str | None = None,
|
1516
|
-
project_id: str
|
1516
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
1517
1517
|
config: dict | StoredInfoTypeConfig | None = None,
|
1518
1518
|
update_mask: dict | FieldMask | None = None,
|
1519
1519
|
retry: Retry | _MethodDefault = DEFAULT,
|
@@ -45,7 +45,11 @@ from requests import Session
|
|
45
45
|
from airflow.exceptions import AirflowException, AirflowProviderDeprecationWarning
|
46
46
|
from airflow.providers.google.cloud.utils.helpers import normalize_directory_path
|
47
47
|
from airflow.providers.google.common.consts import CLIENT_INFO
|
48
|
-
from airflow.providers.google.common.hooks.base_google import
|
48
|
+
from airflow.providers.google.common.hooks.base_google import (
|
49
|
+
PROVIDE_PROJECT_ID,
|
50
|
+
GoogleBaseAsyncHook,
|
51
|
+
GoogleBaseHook,
|
52
|
+
)
|
49
53
|
from airflow.typing_compat import ParamSpec
|
50
54
|
from airflow.utils import timezone
|
51
55
|
from airflow.version import version
|
@@ -1013,7 +1017,7 @@ class GCSHook(GoogleBaseHook):
|
|
1013
1017
|
resource: dict | None = None,
|
1014
1018
|
storage_class: str = "MULTI_REGIONAL",
|
1015
1019
|
location: str = "US",
|
1016
|
-
project_id: str
|
1020
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
1017
1021
|
labels: dict | None = None,
|
1018
1022
|
) -> str:
|
1019
1023
|
"""
|
@@ -22,7 +22,7 @@ from typing import Any, Sequence
|
|
22
22
|
from googleapiclient.discovery import Resource, build
|
23
23
|
|
24
24
|
from airflow.exceptions import AirflowException
|
25
|
-
from airflow.providers.google.common.hooks.base_google import GoogleBaseHook
|
25
|
+
from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook
|
26
26
|
|
27
27
|
|
28
28
|
class GoogleDeploymentManagerHook(GoogleBaseHook):
|
@@ -56,7 +56,7 @@ class GoogleDeploymentManagerHook(GoogleBaseHook):
|
|
56
56
|
@GoogleBaseHook.fallback_to_default_project_id
|
57
57
|
def list_deployments(
|
58
58
|
self,
|
59
|
-
project_id: str
|
59
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
60
60
|
deployment_filter: str | None = None,
|
61
61
|
order_by: str | None = None,
|
62
62
|
) -> list[dict[str, Any]]:
|
@@ -156,7 +156,7 @@ class GKEHook(GoogleBaseHook):
|
|
156
156
|
def get_client(self) -> ClusterManagerClient:
|
157
157
|
return self.get_conn()
|
158
158
|
|
159
|
-
def wait_for_operation(self, operation: Operation, project_id: str
|
159
|
+
def wait_for_operation(self, operation: Operation, project_id: str = PROVIDE_PROJECT_ID) -> Operation:
|
160
160
|
"""Continuously fetch the status from Google Cloud.
|
161
161
|
|
162
162
|
This is done until the given operation completes, or raises an error.
|
@@ -176,7 +176,7 @@ class GKEHook(GoogleBaseHook):
|
|
176
176
|
operation = self.get_operation(operation.name, project_id=project_id or self.project_id)
|
177
177
|
return operation
|
178
178
|
|
179
|
-
def get_operation(self, operation_name: str, project_id: str
|
179
|
+
def get_operation(self, operation_name: str, project_id: str = PROVIDE_PROJECT_ID) -> Operation:
|
180
180
|
"""Get an operation from Google Cloud.
|
181
181
|
|
182
182
|
:param operation_name: Name of operation to fetch
|
@@ -31,7 +31,11 @@ from googleapiclient.discovery import Resource, build
|
|
31
31
|
from googleapiclient.errors import HttpError
|
32
32
|
|
33
33
|
from airflow.exceptions import AirflowException
|
34
|
-
from airflow.providers.google.common.hooks.base_google import
|
34
|
+
from airflow.providers.google.common.hooks.base_google import (
|
35
|
+
PROVIDE_PROJECT_ID,
|
36
|
+
GoogleBaseAsyncHook,
|
37
|
+
GoogleBaseHook,
|
38
|
+
)
|
35
39
|
from airflow.version import version as airflow_version
|
36
40
|
|
37
41
|
if TYPE_CHECKING:
|
@@ -550,7 +554,7 @@ class MLEngineAsyncHook(GoogleBaseAsyncHook):
|
|
550
554
|
def _check_fileds(
|
551
555
|
self,
|
552
556
|
job_id: str,
|
553
|
-
project_id: str
|
557
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
554
558
|
):
|
555
559
|
if not project_id:
|
556
560
|
raise AirflowException("Google Cloud project id is required.")
|
@@ -569,7 +573,7 @@ class MLEngineAsyncHook(GoogleBaseAsyncHook):
|
|
569
573
|
|
570
574
|
return job
|
571
575
|
|
572
|
-
async def get_job(self, job_id: str, session: Session, project_id: str
|
576
|
+
async def get_job(self, job_id: str, session: Session, project_id: str = PROVIDE_PROJECT_ID):
|
573
577
|
"""Get the specified job resource by job ID and project ID."""
|
574
578
|
self._check_fileds(project_id=project_id, job_id=job_id)
|
575
579
|
|
@@ -579,7 +583,7 @@ class MLEngineAsyncHook(GoogleBaseAsyncHook):
|
|
579
583
|
async def get_job_status(
|
580
584
|
self,
|
581
585
|
job_id: str,
|
582
|
-
project_id: str
|
586
|
+
project_id: str = PROVIDE_PROJECT_ID,
|
583
587
|
) -> str | None:
|
584
588
|
"""
|
585
589
|
Poll for job status asynchronously using gcloud-aio.
|
@@ -590,7 +590,7 @@ class PubSubAsyncHook(GoogleBaseAsyncHook):
|
|
590
590
|
|
591
591
|
sync_hook_class = PubSubHook
|
592
592
|
|
593
|
-
def __init__(self, project_id: str
|
593
|
+
def __init__(self, project_id: str = PROVIDE_PROJECT_ID, **kwargs: Any):
|
594
594
|
super().__init__(**kwargs)
|
595
595
|
self.project_id = project_id
|
596
596
|
self._client: SubscriberAsyncClient | None = None
|
@@ -15,16 +15,38 @@
|
|
15
15
|
# KIND, either express or implied. See the License for the
|
16
16
|
# specific language governing permissions and limitations
|
17
17
|
# under the License.
|
18
|
-
"""
|
18
|
+
"""This module contains a Secret Manager hook."""
|
19
19
|
|
20
20
|
from __future__ import annotations
|
21
21
|
|
22
|
-
from
|
22
|
+
from functools import cached_property
|
23
|
+
from typing import TYPE_CHECKING, Sequence
|
23
24
|
|
25
|
+
from deprecated import deprecated
|
26
|
+
from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault
|
27
|
+
from google.cloud.secretmanager_v1 import (
|
28
|
+
AccessSecretVersionResponse,
|
29
|
+
Secret,
|
30
|
+
SecretManagerServiceClient,
|
31
|
+
SecretPayload,
|
32
|
+
SecretVersion,
|
33
|
+
)
|
34
|
+
|
35
|
+
from airflow.exceptions import AirflowProviderDeprecationWarning
|
24
36
|
from airflow.providers.google.cloud._internal_client.secret_manager_client import _SecretManagerClient
|
25
|
-
from airflow.providers.google.common.
|
37
|
+
from airflow.providers.google.common.consts import CLIENT_INFO
|
38
|
+
from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook
|
39
|
+
|
40
|
+
if TYPE_CHECKING:
|
41
|
+
from google.api_core.retry import Retry
|
42
|
+
from google.cloud.secretmanager_v1.services.secret_manager_service.pagers import ListSecretsPager
|
26
43
|
|
27
44
|
|
45
|
+
@deprecated(
|
46
|
+
reason="The SecretsManagerHook is deprecated and will be removed after 01.11.2024. "
|
47
|
+
"Please use GoogleCloudSecretManagerHook instead.",
|
48
|
+
category=AirflowProviderDeprecationWarning,
|
49
|
+
)
|
28
50
|
class SecretsManagerHook(GoogleBaseHook):
|
29
51
|
"""
|
30
52
|
Hook for the Google Secret Manager API.
|
@@ -72,7 +94,7 @@ class SecretsManagerHook(GoogleBaseHook):
|
|
72
94
|
|
73
95
|
@GoogleBaseHook.fallback_to_default_project_id
|
74
96
|
def get_secret(
|
75
|
-
self, secret_id: str, secret_version: str = "latest", project_id: str
|
97
|
+
self, secret_id: str, secret_version: str = "latest", project_id: str = PROVIDE_PROJECT_ID
|
76
98
|
) -> str | None:
|
77
99
|
"""
|
78
100
|
Get secret value from the Secret Manager.
|
@@ -86,3 +108,229 @@ class SecretsManagerHook(GoogleBaseHook):
|
|
86
108
|
secret_version=secret_version,
|
87
109
|
project_id=project_id, # type: ignore
|
88
110
|
)
|
111
|
+
|
112
|
+
|
113
|
+
class GoogleCloudSecretManagerHook(GoogleBaseHook):
|
114
|
+
"""Hook for the Google Cloud Secret Manager API.
|
115
|
+
|
116
|
+
See https://cloud.google.com/secret-manager
|
117
|
+
"""
|
118
|
+
|
119
|
+
@cached_property
|
120
|
+
def client(self):
|
121
|
+
"""Create a Secret Manager Client.
|
122
|
+
|
123
|
+
:return: Secret Manager client.
|
124
|
+
"""
|
125
|
+
return SecretManagerServiceClient(credentials=self.get_credentials(), client_info=CLIENT_INFO)
|
126
|
+
|
127
|
+
def get_conn(self) -> SecretManagerServiceClient:
|
128
|
+
"""Retrieve the connection to Secret Manager.
|
129
|
+
|
130
|
+
:return: Secret Manager client.
|
131
|
+
"""
|
132
|
+
return self.client
|
133
|
+
|
134
|
+
@GoogleBaseHook.fallback_to_default_project_id
|
135
|
+
def create_secret(
|
136
|
+
self,
|
137
|
+
project_id: str,
|
138
|
+
secret_id: str,
|
139
|
+
secret: dict | Secret | None = None,
|
140
|
+
retry: Retry | _MethodDefault = DEFAULT,
|
141
|
+
timeout: float | None = None,
|
142
|
+
metadata: Sequence[tuple[str, str]] = (),
|
143
|
+
) -> Secret:
|
144
|
+
"""Create a secret.
|
145
|
+
|
146
|
+
.. seealso::
|
147
|
+
For more details see API documentation:
|
148
|
+
https://cloud.google.com/python/docs/reference/secretmanager/latest/google.cloud.secretmanager_v1.services.secret_manager_service.SecretManagerServiceClient#google_cloud_secretmanager_v1_services_secret_manager_service_SecretManagerServiceClient_create_secret
|
149
|
+
|
150
|
+
:param project_id: Required. ID of the GCP project that owns the job.
|
151
|
+
If set to ``None`` or missing, the default project_id from the GCP connection is used.
|
152
|
+
:param secret_id: Required. ID of the secret to create.
|
153
|
+
:param secret: Optional. Secret to create.
|
154
|
+
:param retry: Optional. Designation of what errors, if any, should be retried.
|
155
|
+
:param timeout: Optional. The timeout for this request.
|
156
|
+
:param metadata: Optional. Strings which should be sent along with the request as metadata.
|
157
|
+
:return: Secret object.
|
158
|
+
"""
|
159
|
+
_secret = secret or {"replication": {"automatic": {}}}
|
160
|
+
response = self.client.create_secret(
|
161
|
+
request={
|
162
|
+
"parent": f"projects/{project_id}",
|
163
|
+
"secret_id": secret_id,
|
164
|
+
"secret": _secret,
|
165
|
+
},
|
166
|
+
retry=retry,
|
167
|
+
timeout=timeout,
|
168
|
+
metadata=metadata,
|
169
|
+
)
|
170
|
+
self.log.info("Secret Created: %s", response.name)
|
171
|
+
return response
|
172
|
+
|
173
|
+
@GoogleBaseHook.fallback_to_default_project_id
|
174
|
+
def add_secret_version(
|
175
|
+
self,
|
176
|
+
project_id: str,
|
177
|
+
secret_id: str,
|
178
|
+
secret_payload: dict | SecretPayload | None = None,
|
179
|
+
retry: Retry | _MethodDefault = DEFAULT,
|
180
|
+
timeout: float | None = None,
|
181
|
+
metadata: Sequence[tuple[str, str]] = (),
|
182
|
+
) -> SecretVersion:
|
183
|
+
"""Add a version to the secret.
|
184
|
+
|
185
|
+
.. seealso::
|
186
|
+
For more details see API documentation:
|
187
|
+
https://cloud.google.com/python/docs/reference/secretmanager/latest/google.cloud.secretmanager_v1.services.secret_manager_service.SecretManagerServiceClient#google_cloud_secretmanager_v1_services_secret_manager_service_SecretManagerServiceClient_add_secret_version
|
188
|
+
|
189
|
+
:param project_id: Required. ID of the GCP project that owns the job.
|
190
|
+
If set to ``None`` or missing, the default project_id from the GCP connection is used.
|
191
|
+
:param secret_id: Required. ID of the secret to create.
|
192
|
+
:param secret_payload: Optional. A secret payload.
|
193
|
+
:param retry: Optional. Designation of what errors, if any, should be retried.
|
194
|
+
:param timeout: Optional. The timeout for this request.
|
195
|
+
:param metadata: Optional. Strings which should be sent along with the request as metadata.
|
196
|
+
:return: Secret version object.
|
197
|
+
"""
|
198
|
+
response = self.client.add_secret_version(
|
199
|
+
request={
|
200
|
+
"parent": f"projects/{project_id}/secrets/{secret_id}",
|
201
|
+
"payload": secret_payload,
|
202
|
+
},
|
203
|
+
retry=retry,
|
204
|
+
timeout=timeout,
|
205
|
+
metadata=metadata,
|
206
|
+
)
|
207
|
+
self.log.info("Secret version added: %s", response.name)
|
208
|
+
return response
|
209
|
+
|
210
|
+
@GoogleBaseHook.fallback_to_default_project_id
|
211
|
+
def list_secrets(
|
212
|
+
self,
|
213
|
+
project_id: str,
|
214
|
+
page_size: int = 0,
|
215
|
+
page_token: str | None = None,
|
216
|
+
secret_filter: str | None = None,
|
217
|
+
retry: Retry | _MethodDefault = DEFAULT,
|
218
|
+
timeout: float | None = None,
|
219
|
+
metadata: Sequence[tuple[str, str]] = (),
|
220
|
+
) -> ListSecretsPager:
|
221
|
+
"""List secrets.
|
222
|
+
|
223
|
+
.. seealso::
|
224
|
+
For more details see API documentation:
|
225
|
+
https://cloud.google.com/python/docs/reference/secretmanager/latest/google.cloud.secretmanager_v1.services.secret_manager_service.SecretManagerServiceClient#google_cloud_secretmanager_v1_services_secret_manager_service_SecretManagerServiceClient_list_secrets
|
226
|
+
|
227
|
+
:param project_id: Required. ID of the GCP project that owns the job.
|
228
|
+
If set to ``None`` or missing, the default project_id from the GCP connection is used.
|
229
|
+
:param page_size: Optional, number of results to return in the list.
|
230
|
+
:param page_token: Optional, token to provide to skip to a particular spot in the list.
|
231
|
+
:param secret_filter: Optional. Filter string.
|
232
|
+
:param retry: Optional. Designation of what errors, if any, should be retried.
|
233
|
+
:param timeout: Optional. The timeout for this request.
|
234
|
+
:param metadata: Optional. Strings which should be sent along with the request as metadata.
|
235
|
+
:return: Secret List object.
|
236
|
+
"""
|
237
|
+
response = self.client.list_secrets(
|
238
|
+
request={
|
239
|
+
"parent": f"projects/{project_id}",
|
240
|
+
"page_size": page_size,
|
241
|
+
"page_token": page_token,
|
242
|
+
"filter": secret_filter,
|
243
|
+
},
|
244
|
+
retry=retry,
|
245
|
+
timeout=timeout,
|
246
|
+
metadata=metadata,
|
247
|
+
)
|
248
|
+
self.log.info("Secrets list obtained")
|
249
|
+
return response
|
250
|
+
|
251
|
+
@GoogleBaseHook.fallback_to_default_project_id
|
252
|
+
def secret_exists(self, project_id: str, secret_id: str) -> bool:
|
253
|
+
"""Check whether secret exists.
|
254
|
+
|
255
|
+
:param project_id: Required. ID of the GCP project that owns the job.
|
256
|
+
If set to ``None`` or missing, the default project_id from the GCP connection is used.
|
257
|
+
:param secret_id: Required. ID of the secret to find.
|
258
|
+
:return: True if the secret exists, False otherwise.
|
259
|
+
"""
|
260
|
+
secret_filter = f"name:{secret_id}"
|
261
|
+
secret_name = self.client.secret_path(project_id, secret_id)
|
262
|
+
for secret in self.list_secrets(project_id=project_id, page_size=100, secret_filter=secret_filter):
|
263
|
+
if secret.name.split("/")[-1] == secret_id:
|
264
|
+
self.log.info("Secret %s exists.", secret_name)
|
265
|
+
return True
|
266
|
+
self.log.info("Secret %s doesn't exists.", secret_name)
|
267
|
+
return False
|
268
|
+
|
269
|
+
@GoogleBaseHook.fallback_to_default_project_id
|
270
|
+
def access_secret(
|
271
|
+
self,
|
272
|
+
project_id: str,
|
273
|
+
secret_id: str,
|
274
|
+
secret_version: str = "latest",
|
275
|
+
retry: Retry | _MethodDefault = DEFAULT,
|
276
|
+
timeout: float | None = None,
|
277
|
+
metadata: Sequence[tuple[str, str]] = (),
|
278
|
+
) -> AccessSecretVersionResponse:
|
279
|
+
"""Access a secret version.
|
280
|
+
|
281
|
+
.. seealso::
|
282
|
+
For more details see API documentation:
|
283
|
+
https://cloud.google.com/python/docs/reference/secretmanager/latest/google.cloud.secretmanager_v1.services.secret_manager_service.SecretManagerServiceClient#google_cloud_secretmanager_v1_services_secret_manager_service_SecretManagerServiceClient_access_secret_version
|
284
|
+
|
285
|
+
:param project_id: Required. ID of the GCP project that owns the job.
|
286
|
+
If set to ``None`` or missing, the default project_id from the GCP connection is used.
|
287
|
+
:param secret_id: Required. ID of the secret to access.
|
288
|
+
:param secret_version: Optional. Version of the secret to access. Default: latest.
|
289
|
+
:param retry: Optional. Designation of what errors, if any, should be retried.
|
290
|
+
:param timeout: Optional. The timeout for this request.
|
291
|
+
:param metadata: Optional. Strings which should be sent along with the request as metadata.
|
292
|
+
:return: Access secret version response object.
|
293
|
+
"""
|
294
|
+
response = self.client.access_secret_version(
|
295
|
+
request={
|
296
|
+
"name": self.client.secret_version_path(project_id, secret_id, secret_version),
|
297
|
+
},
|
298
|
+
retry=retry,
|
299
|
+
timeout=timeout,
|
300
|
+
metadata=metadata,
|
301
|
+
)
|
302
|
+
self.log.info("Secret version accessed: %s", response.name)
|
303
|
+
return response
|
304
|
+
|
305
|
+
@GoogleBaseHook.fallback_to_default_project_id
|
306
|
+
def delete_secret(
|
307
|
+
self,
|
308
|
+
project_id: str,
|
309
|
+
secret_id: str,
|
310
|
+
retry: Retry | _MethodDefault = DEFAULT,
|
311
|
+
timeout: float | None = None,
|
312
|
+
metadata: Sequence[tuple[str, str]] = (),
|
313
|
+
) -> None:
|
314
|
+
"""Delete a secret.
|
315
|
+
|
316
|
+
.. seealso::
|
317
|
+
For more details see API documentation:
|
318
|
+
https://cloud.google.com/python/docs/reference/secretmanager/latest/google.cloud.secretmanager_v1.services.secret_manager_service.SecretManagerServiceClient#google_cloud_secretmanager_v1_services_secret_manager_service_SecretManagerServiceClient_delete_secret
|
319
|
+
|
320
|
+
:param project_id: Required. ID of the GCP project that owns the job.
|
321
|
+
If set to ``None`` or missing, the default project_id from the GCP connection is used.
|
322
|
+
:param secret_id: Required. ID of the secret to delete.
|
323
|
+
:param retry: Optional. Designation of what errors, if any, should be retried.
|
324
|
+
:param timeout: Optional. The timeout for this request.
|
325
|
+
:param metadata: Optional. Strings which should be sent along with the request as metadata.
|
326
|
+
:return: Access secret version response object.
|
327
|
+
"""
|
328
|
+
name = self.client.secret_path(project_id, secret_id)
|
329
|
+
self.client.delete_secret(
|
330
|
+
request={"name": name},
|
331
|
+
retry=retry,
|
332
|
+
timeout=timeout,
|
333
|
+
metadata=metadata,
|
334
|
+
)
|
335
|
+
self.log.info("Secret deleted: %s", name)
|
336
|
+
return None
|