8000 chore(secretmanager): Add global samples for delayed destory (#13312) · katiemn/python-docs-samples@38ac3ad · GitHub 8000
[go: up one dir, main page]

Skip to content

Commit 38ac3ad

Browse files
authored
chore(secretmanager): Add global samples for delayed destory (GoogleCloudPlatform#13312)
* chore(secretmanager): Add global samples for delayed destroy
1 parent d957e8b commit 38ac3ad

File tree

4 files changed

+260
-0
lines changed

4 files changed

+260
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2025 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
"""
16+
Command line application and sample code for creating a new secret with
17+
delayed_destroy.
18+
"""
19+
20+
import argparse
21+
22+
# [START secretmanager_create_secret_with_delayed_destroy]
23+
24+
# Import the Secret Manager client library.
25+
from google.cloud import secretmanager
26+
from google.protobuf.duration_pb2 import Duration
27+
28+
29+
def create_secret_with_delayed_destroy(
30+
project_id: str,
31+
secret_id: str,
32+
version_destroy_ttl: int,
33+
) -> secretmanager.Secret:
34+
"""
35+
Create a new secret with the given name and version destroy ttl. A
36+
secret is a logical wrapper around a collection of secret versions.
37+
Secret versions hold the actual secret material.
38+
"""
39+
40+
# Create the Secret Manager client.
41+
client = secretmanager.SecretManagerServiceClient()
42+
43+
# Build the resource name of the parent project.
44+
parent = f"projects/{project_id}"
45+
46+
# Create the secret.
47+
response = client.create_secret(
48+
request={
49+
"parent": parent,
50+
"secret_id": secret_id,
51+
"secret": {
52+
"replication": {"automatic": {}},
53+
"version_destroy_ttl": Duration(seconds=version_destroy_ttl),
54+
},
55+
}
56+
)
57+
58+
# Print the new secret name.
59+
print(f"Created secret: {response.name}")
60+
61+
return response
62+
63+
# [END secretmanager_create_secret_with_delayed_destroy]
64+
65+
66+
if __name__ == "__main__":
67+
parser = argparse.ArgumentParser(
68+
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
69+
)
70+
parser.add_argument("project_id", help="id of the GCP project")
71+
parser.add_argument("secret_id", help="id of the secret to create")
72+
parser.add_argument("version_destroy_ttl", help="version_destroy_ttl you want to add")
73+
args = parser.parse_args()
74+
75+
create_secret_with_delayed_destroy(args.project_id, args.secret_id, args.version_destroy_ttl)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2025 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
16+
import argparse
17+
18+
# [START secretmanager_disable_secret_with_delayed_destroy]
19+
20+
# Import the Secret Manager client library.
21+
from google.cloud import secretmanager
22+
23+
24+
def disable_secret_with_delayed_destroy(
25+
project_id: str, secret_id: str
26+
) -> secretmanager.Secret:
27+
"""
28+
Disable the version destroy ttl on the given secret version.
29+
"""
30+
31+
# Create the Secret Manager client.
32+
client = secretmanager.SecretManagerServiceClient()
33+
34+
# Build the resource name of the secret.
35+
name = client.secret_path(project_id, secret_id)
36+
37+
# Delayed destroy of the secret version.
38+
secret = {"name": name}
39+
update_mask = {"paths": ["version_destroy_ttl"]}
40+
response = client.update_secret(request={"secret": secret, "update_mask": update_mask})
41+
42+
# Print the new secret name.
43+
print(f"Disabled delayed destroy on secret: {response.name}")
44+
45+
return response
46+
47+
# [END secretmanager_disable_secret_with_delayed_destroy]
48+
49+
50+
if __name__ == "__main__":
51+
parser = argparse.ArgumentParser(
52+
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
53+
)
54+
parser.add_argument("project_id", help="id of the GCP project")
55+
parser.add_argument("secret_id", help="id of the secret from which to act")
56+
args = parser.parse_args()
57+
58+
disable_secret_with_delayed_destroy(
59+
args.project_id, args.secret_id
60+
)

secretmanager/snippets/snippets_test.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,24 @@
1212
# See the License for the specific language governing permissions and
1313

1414
import base64
15+
from datetime import timedelta
1516
import os
1617
import time
1718
from typing import Iterator, Optional, Tuple, Union
1819
import uuid
1920

2021
from google.api_core import exceptions, retry
2122
from google.cloud import secretmanager
23+
from google.protobuf.duration_pb2 import Duration
24+
2225
import pytest
2326

2427
from access_secret_version import access_secret_version
2528
from add_secret_version import add_secret_version
2629
from consume_event_notification import consume_event_notification
2730
from create_secret import create_secret
2831
from create_secret_with_annotations import create_secret_with_annotations
32+
from create_secret_with_delayed_destroy import create_secret_with_delayed_destroy
2933
from create_secret_with_labels import create_secret_with_labels
3034
from create_secret_with_user_managed_replication import create_ummr_secret
3135
from create_update_secret_label import create_update_secret_label
@@ -36,6 +40,7 @@
3640
from destroy_secret_version_with_etag import destroy_secret_version_with_etag
3741
from disable_secret_version import disable_secret_version
3842
from disable_secret_version_with_etag import disable_secret_version_with_etag
43+
from disable_secret_with_delayed_destroy import disable_secret_with_delayed_destroy
3944
from edit_secret_annotations import edit_secret_annotations
4045
from enable_secret_version import enable_secret_version
4146
from enable_secret_version_with_etag import enable_secret_version_with_etag
@@ -50,6 +55,7 @@
5055
from quickstart import quickstart
5156
from update_secret import update_secret
5257
from update_secret_with_alias import update_secret_with_alias
58+
from update_secret_with_delayed_destroy import update_secret_with_delayed_destroy
5359
from update_secret_with_etag import update_secret_with_etag
5460
from view_secret_annotations import view_secret_annotations
5561
from view_secret_labels import view_secret_labels
@@ -95,6 +101,11 @@ def annotation_value() -> str:
95101
return "annotationvalue"
96102

97103

104+
@pytest.fixture()
105+
def version_destroy_ttl() -> str:
106+
return 604800 # 7 days in seconds
107+
108+
98109
@retry.Retry()
99110
def retry_client_create_secret(
100111
client: secretmanager.SecretManagerServiceClient,
@@ -180,6 +191,33 @@ def secret(
180191
yield project_id, secret_id, secret.etag
181192

182193

194+
@pytest.fixture()
195+
def secret_with_delayed_destroy(
196+
client: secretmanager.SecretManagerServiceClient,
197+
project_id: str,
198+
secret_id: str,
199+
version_destroy_ttl: int,
200+
ttl: Optional[str],
201+
) -> Iterator[Tuple[str, str]]:
202+
print("creating secret with given secret id.")
203+
204+
parent = f"projects/{project_id}"
205+
time.sleep(5)
206+
retry_client_create_secret(
207+
client,
208+
request={
209+
"parent": parent,
210+
"secret_id": secret_id,
211+
"secret": {
212+
"replication": {"automatic": {}},
213+
"version_destroy_ttl": Duration(seconds=version_destroy_ttl),
214+
},
215+
},
216+
)
217+
218+
yield project_id, secret_id
219+
220+
183221
@pytest.fixture()
184222
def secret_version(
185223
client: secretmanager.SecretManagerServiceClient, secret: Tuple[str, str, str]
@@ -288,6 +326,15 @@ def test_create_secret_with_annotations(
288326
assert secret_id in secret.name
289327

290328

329+
def test_create_secret_with_delayed_destroy(
330+
client: secretmanager.SecretManagerServiceClient,
331+
project_id: str, secret_id: str, version_destroy_ttl: int
332+
) -> None:
333+
secret = create_secret_with_delayed_destroy(project_id, secret_id, version_destroy_ttl)
334+
assert secret_id in secret.name
335+
assert timedelta(seconds=version_destroy_ttl) == secret.version_destroy_ttl
336+
337+
291338
def test_delete_secret(
292339
client: secretmanager.SecretManagerServiceClient, secret: Tuple[str, str, str]
293340
) -> None:
@@ -341,6 +388,15 @@ def test_destroy_secret_version_with_etag(
341388
assert version.destroy_time
342389

343390

391+
def test_disable_secret_with_delayed_destroy(
392+
client: secretmanager.SecretManagerServiceClient,
393+
secret_with_delayed_destroy: Tuple[str, str],
394+
) -> None:
395+
project_id, secret_id = secret_with_delayed_destroy
396+
updated_secret = disable_secret_with_delayed_destroy(project_id, secret_id)
397+
assert updated_secret.version_destroy_ttl == timedelta(0)
398+
399+
344400
def test_enable_disable_secret_version(
345401
client: secretmanager.SecretManagerServiceClient,
346402
secret_version: Tuple[str, str, str, str],
@@ -532,3 +588,10 @@ def test_update_secret_with_alias(secret_version: Tuple[str, str, str, str]) ->
532588
project_id, secret_id, version_id, _ = secret_version
533589
secret = update_secret_with_alias(project_id, secret_id)
534590
assert secret.version_aliases["test"] == 1
591+
592+
593+
def test_update_secret_with_delayed_destroy(secret_with_delayed_destroy: Tuple[str, str], version_destroy_ttl: str) -> None:
594+
project_id, secret_id = secret_with_delayed_destroy
595+
updated_version_destroy_ttl_value = 118400
596+
updated_secret = update_secret_with_delayed_destroy(project_id, secret_id, updated_version_destroy_ttl_value)
597+
assert updated_secret.version_destroy_ttl == timedelta(seconds=updated_version_destroy_ttl_value)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2025 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
16+
import argparse
17+
18+
# [START secretmanager_update_secret_with_delayed_destroy]
19+
20+
# Import the Secret Manager client library.
21+
from google.cloud import secretmanager
22+
from google.protobuf.duration_pb2 import Duration
23+
24+
25+
def update_secret_with_delayed_destroy(
26+
project_id: str, secret_id: str, new_version_destroy_ttl: int
27+
) -> secretmanager.UpdateSecretRequest:
28+
"""
29+
Update the version destroy ttl value on an existing secret.
30+
"""
31+
32+
# Create the Secret Manager client.
33+
client = secretmanager.SecretManagerServiceClient()
34+
35+
# Build the resource name of the secret.
36+
name = client.secret_path(project_id, secret_id)
37+
38+
# Update the version_destroy_ttl.
39+
secret = {"name": name, "version_destroy_ttl": Duration(seconds=new_version_destroy_ttl)}
40+
update_mask = {"paths": ["version_destroy_ttl"]}
41+
response = client.update_secret(
42+
request={"secret": secret, "update_mask": update_mask}
43+
)
44+
45+
# Print the new secret name.
46+
print(f"Updated secret: {response.name}")
47+
48+
return response
49+
50+
# [END secretmanager_update_secret_with_delayed_destroy]
51+
52+
53+
if __name__ == "__main__":
54+
parser = argparse.ArgumentParser(
55+
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
56+
)
57+
parser.add_argument("project_id", help="id of the GCP project")
58+
parser.add_argument("secret-id", help="id of the secret to act on")
59+
parser.add_argument("version_destroy_ttl", "new version destroy ttl to be added")
60+
args = parser.parse_args()
61+
62+
update_secret_with_delayed_destroy(args.project_id, args.secret_id, args.version_destroy_ttl)

0 commit comments

Comments
 (0)
0