Skip to content

Commit 0943419

Browse files
feat(secretmanager): Added samples for labels and annotations
1 parent 2d0bb80 commit 0943419

File tree

5 files changed

+265
-0
lines changed

5 files changed

+265
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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+
# [START secretmanager_delete_secret_annotation]
17+
import argparse
18+
19+
# Import the Secret Manager client library.
20+
from google.cloud import secretmanager
21+
22+
23+
def delete_secret_annotation(
24+
project_id: str, secret_id: str, annotation_key: str
25+
) -> secretmanager.UpdateSecretRequest:
26+
"""
27+
Delete a annotation on an existing secret.
28+
"""
29+
30+
# Create the Secret Manager client.
31+
client = secretmanager.SecretManagerServiceClient()
32+
33+
# Build the resource name of the secret.
34+
name = client.secret_path(project_id, secret_id)
35+
36+
# Get the secret.
37+
response = client.get_secret(request={"name": name})
38+
39+
annotations = response.annotations
40+
41+
# Delete the annotation
42+
annotations.pop(annotation_key, None)
43+
44+
# Update the secret.
45+
secret = {"name": name, "annotations": annotations}
46+
update_mask = {"paths": ["annotations"]}
47+
response = client.update_secret(
48+
request={"secret": secret, "update_mask": update_mask}
49+
)
50+
51+
# Print the new secret name.
52+
print(f"Updated secret: {response.name}")
53+
54+
return response
55+
56+
57+
# [END secretmanager_delete_secret_annotation]
58+
59+
if __name__ == "__main__":
60+
parser = argparse.ArgumentParser(
61+
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
62+
)
63+
parser.add_argument("project_id", help="id of the GCP project")
64+
parser.add_argument("secret_id", help="id of the secret to act on")
65+
parser.add_argument("annotation_key", help="key of the annotation to be deleted")
66+
args = parser.parse_args()
67+
68+
delete_secret_annotation(args.project_id, args.secret_id, args.annotation_key)
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+
# [START secretmanager_edit_secret_labels]
17+
18+
import argparse
19+
from typing import Dict
20+
21+
# Import the Secret Manager client library.
22+
from google.cloud import secretmanager
23+
24+
25+
def edit_secret_labels(
26+
project_id: str, secret_id: str, new_labels: Dict[str, str]
27+
) -> secretmanager.UpdateSecretRequest:
28+
"""
29+
Create or update a label 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+
# Get the secret.
39+
response = client.get_secret(request={"name": name})
40+
41+
labels = response.labels
42+
43+
# Update the labels
44+
for label_key in new_labels:
45+
labels[label_key] = new_labels[label_key]
46+
47+
# Update the secret.
48+
secret = {"name": name, "labels": labels}
49+
update_mask = {"paths": ["labels"]}
50+
response = client.update_secret(
51+
request={"secret": secret, "update_mask": update_mask}
52+
)
53+
54+
# Print the new secret name.
55+
print(f"Updated secret: {response.name}")
56+
57+
return response
58+
59+
60+
# [END secretmanager_edit_secret_labels]
61+
62+
if __name__ == "__main__":
63+
parser = argparse.ArgumentParser(
64+
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
65+
)
66+
parser.add_argument("project_id", help="id of the GCP project")
67+
parser.add_argument("secret_id", help="id of the secret to act on")
68+
parser.add_argument("label_key", help="key of the label to be added/updated")
69+
parser.add_argument("label_value", help="value of the label to be added/updated")
70+
args = parser.parse_args()
71+
72+
labels = {args.label_key: args.label_value}
73+
edit_secret_labels(
74+
args.project_id, args.secret_id, labels
75+
)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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+
# [START secretmanager_delete_regional_secret_annotation]
17+
import argparse
18+
19+
# Import the Secret Manager client library.
20+
from google.cloud import secretmanager_v1
21+
22+
23+
def delete_regional_secret_annotation(
24+
project_id: str, location_id: str, secret_id: str, annotation_key: str
25+
) -> secretmanager_v1.UpdateSecretRequest:
26+
"""
27+
Delete a annotation on an existing secret.
28+
"""
29+
30+
# Endpoint to call the regional Secret Manager API.
31+
api_endpoint = f"secretmanager.{location_id}.rep.googleapis.com"
32+
33+
# Create the Secret Manager client.
34+
client = secretmanager_v1.SecretManagerServiceClient(
35+
client_options={"api_endpoint": api_endpoint},
36+
)
37+
38+
# Build the resource name of the parent secret.
39+
name = f"projects/{project_id}/locations/{location_id}/secrets/{secret_id}"
40+
41+
# Get the secret.
42+
response = client.get_secret(request={"name": name})
43+
44+
annotations = response.annotations
45+
46+
# Delete the annotation
47+
annotations.pop(annotation_key, None)
48+
49+
# Update the secret.
50+
secret = {"name": name, "annotations": annotations}
51+
update_mask = {"paths": ["annotations"]}
52+
response = client.update_secret(
53+
request={"secret": secret, "update_mask": update_mask}
54+
)
55+
56+
# Print the new secret name.
57+
print(f"Updated secret: {response.name}")
58+
59+
return response
60+
61+
62+
# [END secretmanager_delete_regional_secret_annotation]
63+
64+
if __name__ == "__main__":
65+
parser = argparse.ArgumentParser(
66+
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
67+
)
68+
parser.add_argument("project_id", help="id of the GCP project")
69+
parser.add_argument(
70+
"location_id", help="id of the location where secret is to be created"
71+
)
72+
parser.add_argument("secret_id", help="id of the secret to act on")
73+
parser.add_argument("annotation_key", help="key of the annotation to be deleted")
74+
args = parser.parse_args()
75+
76+
delete_regional_secret_annotation(
77+
args.project_id, args.location_id, args.secret_id, args.annotation_key
78+
)

secretmanager/snippets/regional_samples/snippets_test.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from regional_samples import create_regional_secret_with_labels
3333
from regional_samples import create_regional_secret_with_tags
3434
from regional_samples import delete_regional_secret
35+
from regional_samples import delete_regional_secret_annotation
3536
from regional_samples import delete_regional_secret_label
3637
from regional_samples import delete_regional_secret_with_etag
3738
from regional_samples import destroy_regional_secret_version
@@ -469,6 +470,24 @@ def test_create_regional_secret_with_label(
469470
assert secret_id in secret.name
470471

471472

473+
def test_delete_regional_secret_annotation(
474+
regional_client: secretmanager_v1.SecretManagerServiceClient,
475+
project_id: str,
476+
location_id: str,
477+
regional_secret: Tuple[str, str],
478+
annotation_key: str,
479+
) -> None:
480+
secret_id, _ = regional_secret
481+
delete_regional_secret_annotation.delete_regional_secret_annotation(
482+
project_id, location_id, secret_id, annotation_key
483+
)
484+
with pytest.raises(exceptions.NotFound):
485+
name = f"projects/{project_id}/locations/{location_id}/secrets/{secret_id}/versions/latest"
486+
retry_client_access_regional_secret_version(
487+
regional_client, request={"name": name}
488+
)
489+
490+
472491
def test_delete_regional_secret_labels(
473492
regional_client: secretmanager_v1.SecretManagerServiceClient,
474493
project_id: str,

secretmanager/snippets/snippets_test.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from create_secret_with_user_managed_replication import create_ummr_secret
3838
from create_update_secret_label import create_update_secret_label
3939
from delete_secret import delete_secret
40+
from delete_secret_annotation import delete_secret_annotation
4041
from delete_secret_label import delete_secret_label
4142
from delete_secret_with_etag import delete_secret_with_etag
4243
from destroy_secret_version import destroy_secret_version
@@ -45,6 +46,7 @@
4546
from disable_secret_version_with_etag import disable_secret_version_with_etag
4647
from disable_secret_with_delayed_destroy import disable_secret_with_delayed_destroy
4748
from edit_secret_annotations import edit_secret_annotations
49+
from edit_secret_labels import edit_secret_labels
4850
from enable_secret_version import enable_secret_version
4951
from enable_secret_version_with_etag import enable_secret_version_with_etag
5052
from get_secret import get_secret
@@ -485,6 +487,19 @@ def test_delete_secret(
485487
retry_client_access_secret_version(client, request={"name": name})
486488

487489

490+
def test_delete_secret_annotation(
491+
client: secretmanager.SecretManagerServiceClient,
492+
secret: Tuple[str, str, str],
493+
annotation_key: str,
494+
) -> None:
495+
project_id, secret_id, _ = secret
496+
delete_secret_annotation(project_id, secret_id, annotation_key)
497+
with pytest.raises(exceptions.NotFound):
498+
print(f"{client}")
499+
name = f"projects/{project_id}/secrets/{secret_id}/versions/latest"
500+
retry_client_access_secret_version(client, request={"name": name})
501+
502+
488503
def test_delete_secret_labels(
489504
client: secretmanager.SecretManagerServiceClient,
490505
secret: Tuple[str, str, str],
@@ -704,6 +719,16 @@ def test_edit_secret_annotations(
704719
assert updated_secret.annotations[annotation_key] == updated_annotation_value
705720

706721

722+
def test_edit_secret_labels(
723+
secret: Tuple[str, str, str], label_key: str
724+
) -> None:
725+
project_id, secret_id, _ = secret
726+
updated_label_value = "updatedlabelvalue"
727+
labels = {label_key: updated_label_value}
728+
updated_secret = edit_secret_labels(project_id, secret_id, labels)
729+
assert updated_secret.labels[label_key] == updated_label_value
730+
731+
707732
def test_update_secret(secret: Tuple[str, str, str]) -> None:
708733
project_id, secret_id, _ = secret
709734
updated_secret = update_secret(project_id, secret_id)

0 commit comments

Comments
 (0)