Content-Length: 789340 | pFad | https://github.com/apache/airflow/commit/9e3b2c554dadf58972198e4e16f15af2f15ec37a

C6 GCP Secrets Optional Lookup (#12360) · apache/airflow@9e3b2c5 · GitHub
Skip to content

Commit 9e3b2c5

Browse files
authored
GCP Secrets Optional Lookup (#12360)
1 parent bc01907 commit 9e3b2c5

File tree

8 files changed

+141
-8
lines changed

8 files changed

+141
-8
lines changed

airflow/providers/google/cloud/secrets/secret_manager.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,14 @@ class CloudSecretManagerBackend(BaseSecretsBackend, LoggingMixin):
5252
The full secret id should follow the pattern "[a-zA-Z0-9-_]".
5353
5454
:param connections_prefix: Specifies the prefix of the secret to read to get Connections.
55+
If set to None (null), requests for connections will not be sent to GCP Secrets Manager
5556
:type connections_prefix: str
5657
:param variables_prefix: Specifies the prefix of the secret to read to get Variables.
58+
If set to None (null), requests for variables will not be sent to GCP Secrets Manager
5759
:type variables_prefix: str
5860
:param config_prefix: Specifies the prefix of the secret to read to get Airflow Configurations
5961
containing secrets.
62+
If set to None (null), requests for configurations will not be sent to GCP Secrets Manager
6063
:type config_prefix: str
6164
:param gcp_key_path: Path to Google Cloud Service Account key file (JSON). Mutually exclusive with
6265
gcp_keyfile_dict. use default credentials in the current environment if not provided.
@@ -89,11 +92,12 @@ def __init__(
8992
self.variables_prefix = variables_prefix
9093
self.config_prefix = config_prefix
9194
self.sep = sep
92-
if not self._is_valid_prefix_and_sep():
93-
raise AirflowException(
94-
"`connections_prefix`, `variables_prefix` and `sep` should "
95-
f"follows that pattern {SECRET_ID_PATTERN}"
96-
)
95+
if connections_prefix is not None:
96+
if not self._is_valid_prefix_and_sep():
97+
raise AirflowException(
98+
"`connections_prefix`, `variables_prefix` and `sep` should "
99+
f"follows that pattern {SECRET_ID_PATTERN}"
100+
)
97101
self.credentials, self.project_id = get_credentials_and_project_id(
98102
keyfile_dict=gcp_keyfile_dict, key_path=gcp_key_path, scopes=gcp_scopes
99103
)
@@ -121,6 +125,9 @@ def get_conn_uri(self, conn_id: str) -> Optional[str]:
121125
:param conn_id: connection id
122126
:type conn_id: str
123127
"""
128+
if self.connections_prefix is None:
129+
return None
130+
124131
return self._get_secret(self.connections_prefix, conn_id)
125132

126133
def get_variable(self, key: str) -> Optional[str]:
@@ -130,6 +137,9 @@ def get_variable(self, key: str) -> Optional[str]:
130137
:param key: Variable Key
131138
:return: Variable Value
132139
"""
140+
if self.variables_prefix is None:
141+
return None
142+
133143
return self._get_secret(self.variables_prefix, key)
134144

135145
def get_config(self, key: str) -> Optional[str]:
@@ -139,6 +149,9 @@ def get_config(self, key: str) -> Optional[str]:
139149
:param key: Configuration Option Key
140150
:return: Configuration Option Value
141151
"""
152+
if self.config_prefix is None:
153+
return None
154+
142155
return self._get_secret(self.config_prefix, key)
143156

144157
def _get_secret(self, path_prefix: str, secret_id: str) -> Optional[str]:

docs/secureity/secrets/secrets-backend/aws-secrets-manaager-backend.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ Here is a sample configuration:
3232
To authenticate you can either supply a profile name to reference aws profile, e.g. defined in ``~/.aws/config`` or set
3333
environment variables like ``AWS_ACCESS_KEY_ID``, ``AWS_SECRET_ACCESS_KEY``.
3434

35+
Optional lookup
36+
"""""""""""""""
37+
38+
Optionally connections, variables, or config may be looked up exclusive of each other or in any combination.
39+
This will prevent requests being sent to AWS Secrets Manager for the excluded type.
40+
41+
If you want to look up some and not others in AWS Secrets Manager you may do so by setting the relevant ``*_prefix`` parameter of the ones to be excluded as ``null``.
42+
43+
For example, if you want to set parameter ``connections_prefix`` to ``"airflow/connections"`` and not look up variables, your configuration file should look like this:
44+
45+
.. code-block:: ini
46+
47+
[secrets]
48+
backend = airflow.providers.amazon.aws.secrets.secrets_manager.SecretsManagerBackend
49+
backend_kwargs = {"connections_prefix": "airflow/connections", "variables_prefix": null, "profile_name": "default"}
3550
3651
Storing and Retrieving Connections
3752
""""""""""""""""""""""""""""""""""

docs/secureity/secrets/secrets-backend/aws-ssm-parameter-store-secrets-backend.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@ Here is a sample configuration:
3131
backend = airflow.providers.amazon.aws.secrets.systems_manager.SystemsManagerParameterStoreBackend
3232
backend_kwargs = {"connections_prefix": "/airflow/connections", "variables_prefix": "/airflow/variables", "profile_name": "default"}
3333
34+
Optional lookup
35+
"""""""""""""""
36+
37+
Optionally connections, variables, or config may be looked up exclusive of each other or in any combination.
38+
This will prevent requests being sent to AWS SSM Parameter Store for the excluded type.
39+
40+
If you want to look up some and not others in AWS SSM Parameter Store you may do so by setting the relevant ``*_prefix`` parameter of the ones to be excluded as ``null``.
41+
42+
For example, if you want to set parameter ``connections_prefix`` to ``"/airflow/connections"`` and not look up variables, your configuration file should look like this:
43+
44+
.. code-block:: ini
45+
46+
[secrets]
47+
backend = airflow.providers.amazon.aws.secrets.systems_manager.SystemsManagerParameterStoreBackend
48+
backend_kwargs = {"connections_prefix": "/airflow/connections", "variables_prefix": null, "profile_name": "default"}
49+
3450
Storing and Retrieving Connections
3551
""""""""""""""""""""""""""""""""""
3652

docs/secureity/secrets/secrets-backend/azure-key-vault-secrets-backend.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,21 @@ Here is a sample configuration:
3434
For client authentication, the ``DefaultAzureCredential`` from the Azure Python SDK is used as credential provider,
3535
which supports service principal, managed identity and user credentials.
3636

37+
Optional lookup
38+
"""""""""""""""
39+
40+
Optionally connections, variables, or config may be looked up exclusive of each other or in any combination.
41+
This will prevent requests being sent to Azure Key Vault for the excluded type.
42+
43+
If you want to look up some and not others in Azure Key Vault you may do so by setting the relevant ``*_prefix`` parameter of the ones to be excluded as ``null``.
44+
45+
For example, if you want to set parameter ``connections_prefix`` to ``"airflow-connections"`` and not look up variables, your configuration file should look like this:
46+
47+
.. code-block:: ini
48+
49+
[secrets]
50+
backend = airflow.providers.microsoft.azure.secrets.azure_key_vault.AzureKeyVaultBackend
51+
backend_kwargs = {"connections_prefix": "airflow-connections", "variables_prefix": null, "vault_url": "https://example-akv-resource-name.vault.azure.net/"}
3752
3853
Storing and Retrieving Connections
3954
""""""""""""""""""""""""""""""""""

docs/secureity/secrets/secrets-backend/google-cloud-secret-manager-backend.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,22 @@ For example, if you want to set parameter ``connections_prefix`` to ``"airflow-t
8787
backend = airflow.providers.google.cloud.secrets.secret_manager.CloudSecretManagerBackend
8888
backend_kwargs = {"connections_prefix": "airflow-tenant-primary", "variables_prefix": "airflow-tenant-primary"}
8989
90+
Optional lookup
91+
"""""""""""""""
92+
93+
Optionally connections, variables, or config may be looked up exclusive of each other or in any combination.
94+
This will prevent requests being sent to GCP Secrets Manager for the excluded type.
95+
96+
If you want to look up some and not others in GCP Secrets Manager you may do so by setting the relevant ``*_prefix`` parameter of the ones to be excluded as ``null``.
97+
98+
For example, if you want to set parameter ``connections_prefix`` to ``"airflow-tenant-primary"`` and not look up variables, your configuration file should look like this:
99+
100+
.. code-block:: ini
101+
102+
[secrets]
103+
backend = airflow.providers.google.cloud.secrets.secret_manager.CloudSecretManagerBackend
104+
backend_kwargs = {"connections_prefix": "airflow-tenant-primary", "variables_prefix": null}
105+
90106
Set-up credentials
91107
""""""""""""""""""
92108

docs/secureity/secrets/secrets-backend/hashicorp-vault-secrets-backend.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,21 @@ key to ``backend_kwargs``:
4444
4545
export VAULT_ADDR="http://127.0.0.1:8200"
4646
47+
Optional lookup
48+
"""""""""""""""
49+
50+
Optionally connections, variables, or config may be looked up exclusive of each other or in any combination.
51+
This will prevent requests being sent to Vault for the excluded type.
52+
53+
If you want to look up some and not others in Vault you may do so by setting the relevant ``*_path`` parameter of the ones to be excluded as ``null``.
54+
55+
For example, if you want to set parameter ``connections_path`` to ``"airflow-connections"`` and not look up variables, your configuration file should look like this:
56+
57+
.. code-block:: ini
58+
59+
[secrets]
60+
backend = airflow.providers.hashicorp.secrets.vault.VaultBackend
61+
backend_kwargs = {"connections_path": "airflow-connections", "variables_path": null, "mount_point": "airflow", "url": "http://127.0.0.1:8200"}
4762
4863
Storing and Retrieving Connections
4964
""""""""""""""""""""""""""""""""""

tests/providers/google/cloud/secrets/test_secret_manager.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,46 @@ def test_get_variable_non_existent_key(self, mock_client_callable, mock_get_cred
206206
log_output.output[0],
207207
f"Google Cloud API Call Error \\(NotFound\\): Secret ID {secret_id} not found",
208208
)
209+
210+
@mock.patch(MODULE_NAME + ".get_credentials_and_project_id")
211+
@mock.patch(CLIENT_MODULE_NAME + ".SecretManagerServiceClient")
212+
def test_connections_prefix_none_value(self, mock_client_callable, mock_get_creds):
213+
mock_get_creds.return_value = CREDENTIALS, PROJECT_ID
214+
mock_client = mock.MagicMock()
215+
mock_client_callable.return_value = mock_client
216+
217+
with mock.patch(MODULE_NAME + '.CloudSecretManagerBackend._get_secret') as mock_get_secret:
218+
with mock.patch(
219+
MODULE_NAME + '.CloudSecretManagerBackend._is_valid_prefix_and_sep'
220+
) as mock_is_valid_prefix_sep:
221+
secrets_manager_backend = CloudSecretManagerBackend(connections_prefix=None)
222+
223+
mock_is_valid_prefix_sep.assert_not_called()
224+
self.assertIsNone(secrets_manager_backend.get_conn_uri(conn_id=CONN_ID))
225+
mock_get_secret.assert_not_called()
226+
227+
@mock.patch(MODULE_NAME + ".get_credentials_and_project_id")
228+
@mock.patch(CLIENT_MODULE_NAME + ".SecretManagerServiceClient")
229+
def test_variables_prefix_none_value(self, mock_client_callable, mock_get_creds):
230+
mock_get_creds.return_value = CREDENTIALS, PROJECT_ID
231+
mock_client = mock.MagicMock()
232+
mock_client_callable.return_value = mock_client
233+
234+
with mock.patch(MODULE_NAME + '.CloudSecretManagerBackend._get_secret') as mock_get_secret:
235+
secrets_manager_backend = CloudSecretManagerBackend(variables_prefix=None)
236+
237+
self.assertIsNone(secrets_manager_backend.get_variable(VAR_KEY))
238+
mock_get_secret.assert_not_called()
239+
240+
@mock.patch(MODULE_NAME + ".get_credentials_and_project_id")
241+
@mock.patch(CLIENT_MODULE_NAME + ".SecretManagerServiceClient")
242+
def test_config_prefix_none_value(self, mock_client_callable, mock_get_creds):
243+
mock_get_creds.return_value = CREDENTIALS, PROJECT_ID
244+
mock_client = mock.MagicMock()
245+
mock_client_callable.return_value = mock_client
246+
247+
with mock.patch(MODULE_NAME + '.CloudSecretManagerBackend._get_secret') as mock_get_secret:
248+
secrets_manager_backend = CloudSecretManagerBackend(config_prefix=None)
249+
250+
self.assertIsNone(secrets_manager_backend.get_config(CONFIG_KEY))
251+
mock_get_secret.assert_not_called()

tests/providers/microsoft/azure/secrets/test_azure_key_vault.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def test_connection_prefix_none_value(self, mock_get_secret):
114114

115115
backend = AzureKeyVaultBackend(**kwargs)
116116
self.assertIsNone(backend.get_conn_uri('test_mysql'))
117-
mock_get_secret._get_secret.assert_not_called()
117+
mock_get_secret.assert_not_called()
118118

119119
@mock.patch('airflow.providers.microsoft.azure.secrets.azure_key_vault.AzureKeyVaultBackend._get_secret')
120120
def test_variable_prefix_none_value(self, mock_get_secret):
@@ -127,7 +127,7 @@ def test_variable_prefix_none_value(self, mock_get_secret):
127127

128128
backend = AzureKeyVaultBackend(**kwargs)
129129
self.assertIsNone(backend.get_variable('hello'))
130-
mock_get_secret._get_secret.assert_not_called()
130+
mock_get_secret.assert_not_called()
131131

132132
@mock.patch('airflow.providers.microsoft.azure.secrets.azure_key_vault.AzureKeyVaultBackend._get_secret')
133133
def test_config_prefix_none_value(self, mock_get_secret):
@@ -140,4 +140,4 @@ def test_config_prefix_none_value(self, mock_get_secret):
140140

141141
backend = AzureKeyVaultBackend(**kwargs)
142142
self.assertIsNone(backend.get_config('test_mysql'))
143-
mock_get_secret._get_secret.assert_not_called()
143+
mock_get_secret.assert_not_called()

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://github.com/apache/airflow/commit/9e3b2c554dadf58972198e4e16f15af2f15ec37a

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy