From e337c21551b685e42b0c8d3f9fffa2fe672a0b01 Mon Sep 17 00:00:00 2001 From: Dhaval Bhensdadiya Date: Wed, 21 Jan 2026 10:58:27 +0530 Subject: [PATCH 1/8] Adding code samples for creating secret with customer managed encryption key and deleting annotations from the secret --- secretmanager/README.md | 4 +- .../secretmanager/CreateSecretWithCmek.java | 76 ++++++++++++++++ .../DeleteSecretAnnotations.java | 77 ++++++++++++++++ .../CreateRegionalSecretWithCmek.java | 75 ++++++++++++++++ .../DeleteRegionalSecretAnnotations.java | 88 +++++++++++++++++++ .../test/java/secretmanager/SnippetsIT.java | 28 +++++- .../regionalsamples/SnippetsIT.java | 29 ++++++ 7 files changed, 375 insertions(+), 2 deletions(-) create mode 100644 secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java create mode 100644 secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java create mode 100644 secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithCmek.java create mode 100644 secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java diff --git a/secretmanager/README.md b/secretmanager/README.md index 0af70bfd6bf..0ffcc0d9ec0 100644 --- a/secretmanager/README.md +++ b/secretmanager/README.md @@ -16,10 +16,12 @@ You must [enable the Secret Manager API](https://console.cloud.google.com/flows/ ### Set Environment Variables -You must set your project ID in order to run the tests +You must set your project ID, KMS Keys (Global and Regional) in order to run the tests ```text $ export GOOGLE_CLOUD_PROJECT= +$ export GOOGLE_CLOUD_REGIONAL_KMS_KEY= (region same as location) +$ export GOOGLE_CLOUD_KMS_KEY= ``` ### Grant Permissions diff --git a/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java b/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java new file mode 100644 index 00000000000..b185047a2e0 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java @@ -0,0 +1,76 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager; + +// [START secretmanager_create_secret_with_annotations] +import com.google.cloud.secretmanager.v1.CustomerManagedEncryption; +import com.google.cloud.secretmanager.v1.ProjectName; +import com.google.cloud.secretmanager.v1.Replication; +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import java.io.IOException; + +public class CreateSecretWithCmek { + + public static void main() throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // This is the id of the secret to act on + String secretId = "your-secret-id"; + // This is the Full kms key name to be used for Cmek. + String kmsKeyName = "your-kms-key-name"; + createSecretWithCmek(projectId, secretId, kmsKeyName); + } + + // Create a secret with annotations. + public static Secret createSecretWithCmek(String projectId, String secretId, String kmsKeyName) + throws IOException { + + // Initialize client that will be used to send requests. This client only needs + // to be created + // once, and can be reused for multiple requests. + try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) { + + // Build the secret name. + ProjectName projectName = ProjectName.of(projectId); + + // Build the Cmek configuration. + CustomerManagedEncryption customerManagedEncryption = + CustomerManagedEncryption.newBuilder().setKmsKeyName(kmsKeyName).build(); + + // Build the replication using Cmek. + Replication secretReplication = + Replication.newBuilder() + .setAutomatic( + Replication.Automatic.newBuilder() + .setCustomerManagedEncryption(customerManagedEncryption) + .build()) + .build(); + + // Build the secret to create with labels. + Secret secret = Secret.newBuilder().setReplication(secretReplication).build(); + + // Create the secret. + Secret createdSecret = client.createSecret(projectName, secretId, secret); + System.out.printf("Created secret %s\n", createdSecret.getName()); + return createdSecret; + } + } +} +// [END secretmanager_create_secret_with_annotations] diff --git a/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java b/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java new file mode 100644 index 00000000000..679d57b357b --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java @@ -0,0 +1,77 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager; + +// [START secretmanager_delete_secret_annotations] +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretName; +import com.google.protobuf.FieldMask; +import com.google.protobuf.util.FieldMaskUtil; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class DeleteSecretAnnotations { + + public static void main() throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // This is the id of the secret to act on + String secretId = "your-secret-id"; + deleteSecretAnnotations(projectId, secretId); + } + + // Delete annotations from an existing secret. + public static Secret deleteSecretAnnotations(String projectId, String secretId) + throws IOException { + // Initialize client that will be used to send requests. This client only needs + // to be created + // once, and can be reused for multiple requests. + try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) { + // Build the name of the secret. + SecretName secretName = SecretName.of(projectId, secretId); + + // Get the current secret + Secret existingSecret = client.getSecret(secretName); + + // Remove all annotations + Map existingAnnotationsMap = + new HashMap(existingSecret.getAnnotationsMap()); + existingAnnotationsMap.clear(); + + // Build the updated secret. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .putAllAnnotations(existingAnnotationsMap) + .build(); + + // Create the field mask for updating only the annotations + FieldMask fieldMask = FieldMaskUtil.fromString("annotations"); + + // Update the secret. + Secret updatedSecret = client.updateSecret(secret, fieldMask); + System.out.printf("Deleted annotations from %s\n", updatedSecret.getName()); + + return updatedSecret; + } + } +} +// [END secretmanager_delete_secret_annotations] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithCmek.java b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithCmek.java new file mode 100644 index 00000000000..21f139bfad6 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithCmek.java @@ -0,0 +1,75 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager.regionalsamples; + +// [START secretmanager_create_regional_secret_with_cmek] +import com.google.cloud.secretmanager.v1.CustomerManagedEncryption; +import com.google.cloud.secretmanager.v1.LocationName; +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; +import java.io.IOException; + +public class CreateRegionalSecretWithCmek { + + public static void main() throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // Location of the secret. + String locationId = "your-location-id"; + // This is the id of the secret to act on + String secretId = "your-secret-id"; + // This is the Full kms key name to be used for Cmek. + String kmsKeyName = "your-kms-key-name"; + createRegionalSecretWithCmek(projectId, locationId, secretId, kmsKeyName); + } + + // Create a new regional secret with customer-managed encryption key. + public static Secret createRegionalSecretWithCmek( + String projectId, String locationId, String secretId, String kmsKeyName) throws IOException { + + // Endpoint to call the regional secret manager server + String apiEndpoint = String.format("secretmanager.%s.rep.googleapis.com:443", locationId); + SecretManagerServiceSettings secretManagerServiceSettings = + SecretManagerServiceSettings.newBuilder().setEndpoint(apiEndpoint).build(); + + // Initialize client that will be used to send requests. This client only needs + // to be created + // once, and can be reused for multiple requests. + try (SecretManagerServiceClient client = + SecretManagerServiceClient.create(secretManagerServiceSettings)) { + // Build the parent name from the project and location. + LocationName locationName = LocationName.of(projectId, locationId); + + // Build the customer-managed encryption configuration. + CustomerManagedEncryption customerManagedEncryption = + CustomerManagedEncryption.newBuilder().setKmsKeyName(kmsKeyName).build(); + + // Build the secret with customer-managed encryption key. + Secret secret = + Secret.newBuilder().setCustomerManagedEncryption(customerManagedEncryption).build(); + + // Create the secret. + Secret createdSecret = client.createSecret(locationName.toString(), secretId, secret); + System.out.printf("Created secret %s\n", createdSecret.getName()); + return createdSecret; + } + } +} +// [END secretmanager_create_regional_secret_with_cmek] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java new file mode 100644 index 00000000000..ddd4c46fa40 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java @@ -0,0 +1,88 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager.regionalsamples; + +// [START secretmanager_delete_regional_secret_annotations] +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; +import com.google.cloud.secretmanager.v1.SecretName; +import com.google.protobuf.FieldMask; +import com.google.protobuf.util.FieldMaskUtil; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class DeleteRegionalSecretAnnotations { + + public static void main() throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // Location of the secret. + String locationId = "your-location-id"; + // This is the id of the secret to act on + String secretId = "your-secret-id"; + deleteRegionalSecretAnnotations(projectId, locationId, secretId); + } + + // Delete annotations from an existing regional secret. + public static Secret deleteRegionalSecretAnnotations( + String projectId, String locationId, String secretId) throws IOException { + + // Endpoint to call the regional secret manager server + String apiEndpoint = String.format("secretmanager.%s.rep.googleapis.com:443", locationId); + SecretManagerServiceSettings secretManagerServiceSettings = + SecretManagerServiceSettings.newBuilder().setEndpoint(apiEndpoint).build(); + + // Initialize client that will be used to send requests. This client only needs + // to be created + // once, and can be reused for multiple requests. + try (SecretManagerServiceClient client = + SecretManagerServiceClient.create(secretManagerServiceSettings)) { + // Build the name of the secret. + SecretName secretName = + SecretName.ofProjectLocationSecretName(projectId, locationId, secretId); + + // Get the current secret + Secret existingSecret = client.getSecret(secretName); + + // Remove all annotations + Map existingAnnotationsMap = + new HashMap(existingSecret.getAnnotationsMap()); + existingAnnotationsMap.clear(); + + // Build the updated secret. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .putAllAnnotations(existingAnnotationsMap) + .build(); + + // Create the field mask for updating only the annotations + FieldMask fieldMask = FieldMaskUtil.fromString("annotations"); + + // Update the secret. + Secret updatedSecret = client.updateSecret(secret, fieldMask); + System.out.printf("Deleted annotations from %s\n", updatedSecret.getName()); + + return updatedSecret; + } + } +} +// [END secretmanager_delete_regional_secret_annotations] diff --git a/secretmanager/src/test/java/secretmanager/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/SnippetsIT.java index 41f88a1e6d9..81d58119be4 100644 --- a/secretmanager/src/test/java/secretmanager/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/SnippetsIT.java @@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.api.gax.longrunning.OperationFuture; import com.google.cloud.resourcemanager.v3.CreateTagKeyMetadata; @@ -77,11 +78,13 @@ public class SnippetsIT { private static final String IAM_USER = "serviceAccount:iam-samples@java-docs-samples-testing.iam.gserviceaccount.com"; private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static final String KMS_KEY_NAME = System.getenv("GOOGLE_CLOUD_KMS_KEY"); private static final String LABEL_KEY = "examplelabelkey"; private static final String LABEL_VALUE = "examplelabelvalue"; private static final String UPDATED_LABEL_KEY = "updatedlabelkey"; private static final String UPDATED_LABEL_VALUE = "updatedlabelvalue"; - private static final String ANNOTATION_KEY = "exampleannotationkey"; + private static final String ANNOTATION_KEY = + "exampleannotationkey"; private static final String ANNOTATION_VALUE = "exampleannotationvalue"; private static final String UPDATED_ANNOTATION_KEY = "updatedannotationkey"; private static final String UPDATED_ANNOTATION_VALUE = "updatedannotationvalue"; @@ -96,6 +99,7 @@ public class SnippetsIT { private static SecretName TEST_SECRET_WITH_LABEL_TO_CREATE_NAME; private static SecretName TEST_SECRET_WITH_TAGS_TO_CREATE_NAME; private static SecretName TEST_SECRET_WITH_ANNOTATION_TO_CREATE_NAME; + private static SecretName TEST_SECRET_WITH_CMEK_TO_CREATE_NAME; private static SecretName TEST_UMMR_SECRET_TO_CREATE_NAME; private static SecretVersion TEST_SECRET_VERSION; private static SecretVersion TEST_SECRET_VERSION_TO_DESTROY; @@ -125,6 +129,7 @@ public static void beforeAll() throws Exception { TEST_SECRET_WITH_TAGS_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); TEST_SECRET_WITH_LABEL_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); TEST_SECRET_WITH_ANNOTATION_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); + TEST_SECRET_WITH_CMEK_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); TEST_SECRET_VERSION = addSecretVersion(TEST_SECRET_WITH_VERSIONS); TEST_SECRET_VERSION_TO_DESTROY = addSecretVersion(TEST_SECRET_WITH_VERSIONS); @@ -154,12 +159,14 @@ public void afterEach() { @AfterClass public static void afterAll() throws Exception { Assert.assertFalse("missing GOOGLE_CLOUD_PROJECT", Strings.isNullOrEmpty(PROJECT_ID)); + Assert.assertFalse("missing GOOGLE_CLOUD_KMS_KEY", Strings.isNullOrEmpty(KMS_KEY_NAME)); deleteSecret(TEST_SECRET.getName()); deleteSecret(TEST_SECRET_TO_CREATE_NAME.toString()); deleteSecret(TEST_SECRET_WITH_TAGS_TO_CREATE_NAME.toString()); deleteSecret(TEST_SECRET_WITH_LABEL_TO_CREATE_NAME.toString()); deleteSecret(TEST_SECRET_WITH_ANNOTATION_TO_CREATE_NAME.toString()); + deleteSecret(TEST_SECRET_WITH_CMEK_TO_CREATE_NAME.toString()); deleteSecret(TEST_UMMR_SECRET_TO_CREATE_NAME.toString()); deleteSecret(TEST_SECRET_TO_DELETE.getName()); deleteSecret(TEST_SECRET_TO_DELETE_WITH_ETAG.getName()); @@ -367,6 +374,16 @@ public void testCreateSecretWithAnnotations() throws IOException { assertThat(secret.getAnnotationsMap()).containsEntry(ANNOTATION_KEY, ANNOTATION_VALUE); } + @Test + public void testCreateSecretWithCmek() throws IOException { + SecretName name = TEST_SECRET_WITH_CMEK_TO_CREATE_NAME; + Secret secret = CreateSecretWithCmek.createSecretWithCmek( + name.getProject(), name.getSecret(), KMS_KEY_NAME); + + assertThat(secret.getReplication().getAutomatic().getCustomerManagedEncryption() + .getKmsKeyName()).isEqualTo(KMS_KEY_NAME); + } + @Test public void testCreateSecretWithUserManagedReplication() throws IOException { SecretName name = TEST_UMMR_SECRET_TO_CREATE_NAME; @@ -581,6 +598,15 @@ public void testEditSecretAnnotations() throws IOException { UPDATED_ANNOTATION_KEY, UPDATED_ANNOTATION_VALUE); } + @Test + public void testDeleteSecretAnnotations() throws IOException { + SecretName name = SecretName.parse(TEST_SECRET.getName()); + Secret updatedSecret = + DeleteSecretAnnotations.deleteSecretAnnotations(name.getProject(), name.getSecret()); + + assertTrue(updatedSecret.getAnnotationsMap().isEmpty()); + } + @Test public void testUpdateSecretWithAlias() throws IOException { SecretName name = SecretName.parse(TEST_SECRET_WITH_VERSIONS.getName()); diff --git a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java index 11ca876dc30..59aab3567bf 100644 --- a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java @@ -83,6 +83,8 @@ public class SnippetsIT { private static final String IAM_USER = "serviceAccount:iam-samples@java-docs-samples-testing.iam.gserviceaccount.com"; private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static final String REGIONAL_KMS_KEY_NAME = + System.getenv("GOOGLE_CLOUD_REGIONAL_KMS_KEY"); private static final String LABEL_KEY = "examplelabelkey"; private static final String LABEL_VALUE = "examplelabelvalue"; private static final String UPDATED_LABEL_KEY = "updatedlabelkey"; @@ -105,6 +107,7 @@ public class SnippetsIT { private static SecretName TEST_REGIONAL_SECRET_WITH_LABEL_TO_CREATE_NAME; private static SecretName TEST_REGIONAL_SECRET_WITH_TAGS_TO_CREATE_NAME; private static SecretName TEST_REGIONAL_SECRET_WITH_ANNOTATION_TO_CREATE_NAME; + private static SecretName TEST_REGIONAL_SECRET_WITH_CMEK_TO_CREATE_NAME; private static SecretVersion TEST_REGIONAL_SECRET_VERSION; private static SecretVersion TEST_REGIONAL_SECRET_VERSION_TO_DESTROY; private static SecretVersion TEST_REGIONAL_SECRET_VERSION_TO_DESTROY_WITH_ETAG; @@ -123,6 +126,8 @@ public static void beforeAll() throws Exception { Assert.assertFalse("missing GOOGLE_CLOUD_PROJECT", Strings.isNullOrEmpty(PROJECT_ID)); Assert.assertFalse("missing GOOGLE_CLOUD_PROJECT_LOCATION", Strings.isNullOrEmpty(LOCATION_ID)); + Assert.assertFalse("missing REGIONAL_KMS_KEY_NAME", + Strings.isNullOrEmpty(REGIONAL_KMS_KEY_NAME)); TEST_REGIONAL_SECRET = createRegionalSecret(); TEST_REGIONAL_SECRET_TO_DELETE = createRegionalSecret(); @@ -135,6 +140,8 @@ public static void beforeAll() throws Exception { SecretName.ofProjectLocationSecretName(PROJECT_ID, LOCATION_ID, randomSecretId()); TEST_REGIONAL_SECRET_WITH_ANNOTATION_TO_CREATE_NAME = SecretName.ofProjectLocationSecretName(PROJECT_ID, LOCATION_ID, randomSecretId()); + TEST_REGIONAL_SECRET_WITH_CMEK_TO_CREATE_NAME = + SecretName.ofProjectLocationSecretName(PROJECT_ID, LOCATION_ID, randomSecretId()); TEST_REGIONAL_SECRET_WITH_LABEL_TO_CREATE_NAME = SecretName.ofProjectLocationSecretName(PROJECT_ID, LOCATION_ID, randomSecretId()); @@ -180,6 +187,7 @@ public static void afterAll() throws Exception { deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_LABEL_TO_CREATE_NAME.toString()); deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_TAGS_TO_CREATE_NAME.toString()); deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_ANNOTATION_TO_CREATE_NAME.toString()); + deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_CMEK_TO_CREATE_NAME.toString()); deleteRegionalSecret(TEST_REGIONAL_SECRET_TO_DELETE.getName()); deleteRegionalSecret(TEST_REGIONAL_SECRET_TO_DELETE_WITH_ETAG.getName()); deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_VERSIONS.getName()); @@ -398,6 +406,17 @@ public void testCreateRegionalSecretWithAnnotations() throws IOException { assertEquals(name.getSecret(), createdSecretName.getSecret()); } + @Test + public void testCreateRegionalSecretWithCmek() throws IOException { + SecretName name = TEST_REGIONAL_SECRET_WITH_CMEK_TO_CREATE_NAME; + Secret secret = CreateRegionalSecretWithCmek.createRegionalSecretWithCmek( + name.getProject(), name.getLocation(), name.getSecret(), REGIONAL_KMS_KEY_NAME); + + assertThat( + secret.getCustomerManagedEncryption().getKmsKeyName() + ).isEqualTo(REGIONAL_KMS_KEY_NAME); + } + @Test public void testDeleteRegionalSecret() throws IOException { SecretName name = SecretName.parse(TEST_REGIONAL_SECRET_TO_DELETE.getName()); @@ -682,6 +701,16 @@ public void testEditSecretAnnotations() throws IOException { UPDATED_ANNOTATION_KEY, UPDATED_ANNOTATION_VALUE); } + @Test + public void testDeleteRegionalSecretAnnotations() throws IOException { + SecretName name = SecretName.parse(TEST_REGIONAL_SECRET.getName()); + Secret updatedSecret = DeleteRegionalSecretAnnotations.deleteRegionalSecretAnnotations( + name.getProject(), name.getLocation(), name.getSecret()); + + assertTrue(updatedSecret.getAnnotationsMap().isEmpty()); + } + + @Test public void testCreateRegionalSecretWithDelayedDestroy() throws IOException { SecretName name = TEST_REGIONAL_SECRET_WITH_DELAYED_DESTROY; From 36203bb30aefeab19e4c0ca7168d01fa0a8f341f Mon Sep 17 00:00:00 2001 From: Dhaval Bhensdadiya Date: Wed, 21 Jan 2026 11:30:47 +0530 Subject: [PATCH 2/8] Improved readme and created new secret specific for deleting annotations --- secretmanager/README.md | 3 ++- secretmanager/src/test/java/secretmanager/SnippetsIT.java | 5 ++++- .../test/java/secretmanager/regionalsamples/SnippetsIT.java | 5 ++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/secretmanager/README.md b/secretmanager/README.md index 0ffcc0d9ec0..72e712540d1 100644 --- a/secretmanager/README.md +++ b/secretmanager/README.md @@ -12,7 +12,7 @@ the Secret Manager API using the Google Java API Client Libraries. ### Enable the API -You must [enable the Secret Manager API](https://console.cloud.google.com/flows/enableapi?apiid=secretmanager.googleapis.com) for your project in order to use these samples +You must enable the [Secret Manager API](https://console.cloud.google.com/flows/enableapi?apiid=secretmanager.googleapis.com) and [Cloud KMS API](https://console.cloud.google.com/flows/enableapi?apiid=cloudkms.googleapis.com) for your project in order to use these samples ### Set Environment Variables @@ -30,5 +30,6 @@ You must ensure that the [user account or service account](https://cloud.google. * Secret Manager Admin (`roles/secretmanager.admin`) * Secret Manager Secret Accessor (`roles/secretmanager.secretAccessor`) +* Cloud KMS Encrypter / Decrypter (`roles/cloudkms.cryptoKeyEncrypterDecrypter`) on the regional and global KMS key used for testing More information can be found in the [Secret Manager Docs](https://cloud.google.com/secret-manager/docs/access-control) diff --git a/secretmanager/src/test/java/secretmanager/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/SnippetsIT.java index 81d58119be4..e2c6a362a45 100644 --- a/secretmanager/src/test/java/secretmanager/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/SnippetsIT.java @@ -92,6 +92,7 @@ public class SnippetsIT { private static Secret TEST_SECRET; private static Secret TEST_SECRET_TO_DELETE; private static Secret TEST_SECRET_TO_DELETE_WITH_ETAG; + private static Secret TEST_SECRET_TO_DELETE_ANNOTATIONS; private static Secret TEST_SECRET_TO_DELAYED_DESTROY; private static Secret TEST_SECRET_WITH_VERSIONS; private static SecretName TEST_SECRET_WITH_DELAYED_DESTROY; @@ -121,6 +122,7 @@ public static void beforeAll() throws Exception { TEST_SECRET = createSecret(true); TEST_SECRET_TO_DELETE = createSecret(false); TEST_SECRET_TO_DELETE_WITH_ETAG = createSecret(false); + TEST_SECRET_TO_DELETE_ANNOTATIONS = createSecret(true); TEST_SECRET_WITH_VERSIONS = createSecret(false); TEST_SECRET_TO_DELAYED_DESTROY = createSecret(false); TEST_SECRET_WITH_DELAYED_DESTROY = SecretName.of(PROJECT_ID, randomSecretId()); @@ -170,6 +172,7 @@ public static void afterAll() throws Exception { deleteSecret(TEST_UMMR_SECRET_TO_CREATE_NAME.toString()); deleteSecret(TEST_SECRET_TO_DELETE.getName()); deleteSecret(TEST_SECRET_TO_DELETE_WITH_ETAG.getName()); + deleteSecret(TEST_SECRET_TO_DELETE_ANNOTATIONS.getName()); deleteSecret(TEST_SECRET_WITH_VERSIONS.getName()); deleteSecret(TEST_SECRET_WITH_DELAYED_DESTROY.toString()); deleteSecret(TEST_SECRET_TO_DELAYED_DESTROY.getName()); @@ -600,7 +603,7 @@ public void testEditSecretAnnotations() throws IOException { @Test public void testDeleteSecretAnnotations() throws IOException { - SecretName name = SecretName.parse(TEST_SECRET.getName()); + SecretName name = SecretName.parse(TEST_SECRET_TO_DELETE_ANNOTATIONS.getName()); Secret updatedSecret = DeleteSecretAnnotations.deleteSecretAnnotations(name.getProject(), name.getSecret()); diff --git a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java index 59aab3567bf..067a69b1e33 100644 --- a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java @@ -100,6 +100,7 @@ public class SnippetsIT { private static Secret TEST_REGIONAL_SECRET; private static Secret TEST_REGIONAL_SECRET_TO_DELETE; private static Secret TEST_REGIONAL_SECRET_TO_DELETE_WITH_ETAG; + private static Secret TEST_REGIONAL_SECRET_TO_DELETE_ANNOTATIONS; private static Secret TEST_REGIONAL_SECRET_WITH_VERSIONS; private static Secret TEST_REGIONAL_SECRET_TO_DELAYED_DESTROY; private static SecretName TEST_REGIONAL_SECRET_WITH_DELAYED_DESTROY; @@ -132,6 +133,7 @@ public static void beforeAll() throws Exception { TEST_REGIONAL_SECRET = createRegionalSecret(); TEST_REGIONAL_SECRET_TO_DELETE = createRegionalSecret(); TEST_REGIONAL_SECRET_TO_DELETE_WITH_ETAG = createRegionalSecret(); + TEST_REGIONAL_SECRET_TO_DELETE_ANNOTATIONS = createRegionalSecret(); TEST_REGIONAL_SECRET_WITH_VERSIONS = createRegionalSecret(); TEST_REGIONAL_SECRET_TO_DELAYED_DESTROY = createRegionalSecret(); TEST_REGIONAL_SECRET_WITH_DELAYED_DESTROY = @@ -190,6 +192,7 @@ public static void afterAll() throws Exception { deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_CMEK_TO_CREATE_NAME.toString()); deleteRegionalSecret(TEST_REGIONAL_SECRET_TO_DELETE.getName()); deleteRegionalSecret(TEST_REGIONAL_SECRET_TO_DELETE_WITH_ETAG.getName()); + deleteRegionalSecret(TEST_REGIONAL_SECRET_TO_DELETE_ANNOTATIONS.getName()); deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_VERSIONS.getName()); deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_DELAYED_DESTROY.toString()); deleteRegionalSecret(TEST_REGIONAL_SECRET_TO_DELAYED_DESTROY.getName()); @@ -703,7 +706,7 @@ public void testEditSecretAnnotations() throws IOException { @Test public void testDeleteRegionalSecretAnnotations() throws IOException { - SecretName name = SecretName.parse(TEST_REGIONAL_SECRET.getName()); + SecretName name = SecretName.parse(TEST_REGIONAL_SECRET_TO_DELETE_ANNOTATIONS.getName()); Secret updatedSecret = DeleteRegionalSecretAnnotations.deleteRegionalSecretAnnotations( name.getProject(), name.getLocation(), name.getSecret()); From 0acae1650bc78396a90c357f974dcb8ddbafb5c2 Mon Sep 17 00:00:00 2001 From: dhavalbhensdadiya-crest Date: Wed, 21 Jan 2026 11:38:44 +0530 Subject: [PATCH 3/8] Applied suggestions from code review Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../java/secretmanager/CreateSecretWithCmek.java | 8 ++++---- .../java/secretmanager/DeleteSecretAnnotations.java | 12 ++---------- .../DeleteRegionalSecretAnnotations.java | 12 ++---------- 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java b/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java index b185047a2e0..64d23cceefd 100644 --- a/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java +++ b/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java @@ -16,7 +16,7 @@ package secretmanager; -// [START secretmanager_create_secret_with_annotations] +// [START secretmanager_create_secret_with_cmek] import com.google.cloud.secretmanager.v1.CustomerManagedEncryption; import com.google.cloud.secretmanager.v1.ProjectName; import com.google.cloud.secretmanager.v1.Replication; @@ -38,7 +38,7 @@ public static void main() throws IOException { createSecretWithCmek(projectId, secretId, kmsKeyName); } - // Create a secret with annotations. + // Create a secret with a customer-managed encryption key (CMEK). public static Secret createSecretWithCmek(String projectId, String secretId, String kmsKeyName) throws IOException { @@ -63,7 +63,7 @@ public static Secret createSecretWithCmek(String projectId, String secretId, Str .build()) .build(); - // Build the secret to create with labels. + // Build the secret to create with the replication policy. Secret secret = Secret.newBuilder().setReplication(secretReplication).build(); // Create the secret. @@ -73,4 +73,4 @@ public static Secret createSecretWithCmek(String projectId, String secretId, Str } } } -// [END secretmanager_create_secret_with_annotations] +// [END secretmanager_create_secret_with_cmek] diff --git a/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java b/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java index 679d57b357b..20a6f9cc5cb 100644 --- a/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java +++ b/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java @@ -48,19 +48,11 @@ public static Secret deleteSecretAnnotations(String projectId, String secretId) // Build the name of the secret. SecretName secretName = SecretName.of(projectId, secretId); - // Get the current secret - Secret existingSecret = client.getSecret(secretName); - - // Remove all annotations - Map existingAnnotationsMap = - new HashMap(existingSecret.getAnnotationsMap()); - existingAnnotationsMap.clear(); - - // Build the updated secret. + // Build the updated secret with an empty annotations map. Secret secret = Secret.newBuilder() .setName(secretName.toString()) - .putAllAnnotations(existingAnnotationsMap) + .putAllAnnotations(new HashMap<>()) .build(); // Create the field mask for updating only the annotations diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java index ddd4c46fa40..fd34f0db992 100644 --- a/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java @@ -59,19 +59,11 @@ public static Secret deleteRegionalSecretAnnotations( SecretName secretName = SecretName.ofProjectLocationSecretName(projectId, locationId, secretId); - // Get the current secret - Secret existingSecret = client.getSecret(secretName); - - // Remove all annotations - Map existingAnnotationsMap = - new HashMap(existingSecret.getAnnotationsMap()); - existingAnnotationsMap.clear(); - - // Build the updated secret. + // Build the updated secret with an empty annotations map. Secret secret = Secret.newBuilder() .setName(secretName.toString()) - .putAllAnnotations(existingAnnotationsMap) + .putAllAnnotations(new HashMap<>()) .build(); // Create the field mask for updating only the annotations From 9d6e4ee2d3e7adf475b49165638efe78a20c8c39 Mon Sep 17 00:00:00 2001 From: Dhaval Bhensdadiya Date: Thu, 22 Jan 2026 12:49:52 +0530 Subject: [PATCH 4/8] Added args to main function --- .../src/main/java/secretmanager/CreateSecretWithCmek.java | 2 +- .../src/main/java/secretmanager/DeleteSecretAnnotations.java | 4 ++-- .../regionalsamples/CreateRegionalSecretWithCmek.java | 2 +- .../regionalsamples/DeleteRegionalSecretAnnotations.java | 3 +-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java b/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java index 64d23cceefd..4f4fae9f911 100644 --- a/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java +++ b/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java @@ -26,7 +26,7 @@ public class CreateSecretWithCmek { - public static void main() throws IOException { + public static void main(String[] args) throws IOException { // TODO(developer): Replace these variables before running the sample. // This is the id of the GCP project diff --git a/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java b/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java index 20a6f9cc5cb..c689d1bc813 100644 --- a/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java +++ b/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java @@ -24,11 +24,11 @@ import com.google.protobuf.util.FieldMaskUtil; import java.io.IOException; import java.util.HashMap; -import java.util.Map; public class DeleteSecretAnnotations { - public static void main() throws IOException { + + public static void main(String[] args) throws IOException { // TODO(developer): Replace these variables before running the sample. // This is the id of the GCP project diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithCmek.java b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithCmek.java index 21f139bfad6..ac52811d658 100644 --- a/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithCmek.java +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithCmek.java @@ -26,7 +26,7 @@ public class CreateRegionalSecretWithCmek { - public static void main() throws IOException { + public static void main(String[] args) throws IOException { // TODO(developer): Replace these variables before running the sample. // This is the id of the GCP project diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java index fd34f0db992..babbd3ef636 100644 --- a/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.java @@ -25,11 +25,10 @@ import com.google.protobuf.util.FieldMaskUtil; import java.io.IOException; import java.util.HashMap; -import java.util.Map; public class DeleteRegionalSecretAnnotations { - public static void main() throws IOException { + public static void main(String[] args) throws IOException { // TODO(developer): Replace these variables before running the sample. // This is the id of the GCP project From 710bb85be44637d01d776403c2ae197b9cd314f0 Mon Sep 17 00:00:00 2001 From: Dhaval Bhensdadiya Date: Thu, 22 Jan 2026 15:36:43 +0530 Subject: [PATCH 5/8] Moved KMS key validation check to BeforeClass setup --- secretmanager/src/test/java/secretmanager/SnippetsIT.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/secretmanager/src/test/java/secretmanager/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/SnippetsIT.java index e2c6a362a45..fd219a3607a 100644 --- a/secretmanager/src/test/java/secretmanager/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/SnippetsIT.java @@ -118,6 +118,7 @@ public class SnippetsIT { @BeforeClass public static void beforeAll() throws Exception { Assert.assertFalse("missing GOOGLE_CLOUD_PROJECT", Strings.isNullOrEmpty(PROJECT_ID)); + Assert.assertFalse("missing GOOGLE_CLOUD_KMS_KEY", Strings.isNullOrEmpty(KMS_KEY_NAME)); TEST_SECRET = createSecret(true); TEST_SECRET_TO_DELETE = createSecret(false); @@ -160,8 +161,6 @@ public void afterEach() { @AfterClass public static void afterAll() throws Exception { - Assert.assertFalse("missing GOOGLE_CLOUD_PROJECT", Strings.isNullOrEmpty(PROJECT_ID)); - Assert.assertFalse("missing GOOGLE_CLOUD_KMS_KEY", Strings.isNullOrEmpty(KMS_KEY_NAME)); deleteSecret(TEST_SECRET.getName()); deleteSecret(TEST_SECRET_TO_CREATE_NAME.toString()); From bfbc85c510c580636a9cd8af80a0f5d6d824cb50 Mon Sep 17 00:00:00 2001 From: Dhaval Bhensdadiya Date: Thu, 22 Jan 2026 11:44:21 +0530 Subject: [PATCH 6/8] feat(secretmanager): add examples for listing, binding and removing tags from secrets --- .../java/secretmanager/BindSecretTag.java | 64 ++++++++++++++++ .../secretmanager/ListSecretTagBindings.java | 58 +++++++++++++++ .../secretmanager/RemoveTagFromSecret.java | 64 ++++++++++++++++ .../BindRegionalSecretTag.java | 74 +++++++++++++++++++ .../ListRegionalSecretTagBindings.java | 66 +++++++++++++++++ .../RemoveTagFromRegionalSecret.java | 74 +++++++++++++++++++ .../test/java/secretmanager/SnippetsIT.java | 33 +++++++++ .../regionalsamples/SnippetsIT.java | 39 ++++++++++ 8 files changed, 472 insertions(+) create mode 100644 secretmanager/src/main/java/secretmanager/BindSecretTag.java create mode 100644 secretmanager/src/main/java/secretmanager/ListSecretTagBindings.java create mode 100644 secretmanager/src/main/java/secretmanager/RemoveTagFromSecret.java create mode 100644 secretmanager/src/main/java/secretmanager/regionalsamples/BindRegionalSecretTag.java create mode 100644 secretmanager/src/main/java/secretmanager/regionalsamples/ListRegionalSecretTagBindings.java create mode 100644 secretmanager/src/main/java/secretmanager/regionalsamples/RemoveTagFromRegionalSecret.java diff --git a/secretmanager/src/main/java/secretmanager/BindSecretTag.java b/secretmanager/src/main/java/secretmanager/BindSecretTag.java new file mode 100644 index 00000000000..fb18ad4bff3 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/BindSecretTag.java @@ -0,0 +1,64 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager; + +// [START secretmanager_bind_secret_tag] +import com.google.cloud.resourcemanager.v3.CreateTagBindingRequest; +import com.google.cloud.resourcemanager.v3.TagBinding; +import com.google.cloud.resourcemanager.v3.TagBindingsClient; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class BindSecretTag { + + public static void main(String[] args) throws Exception { + // TODO(developer): replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // This is the id of the secret to act on + String secretId = "your-secret-id"; + // Tag value to bind, e.g. "tagValues/123" + String tagValueName = "your-tag-value"; + + bindSecretTag(projectId, secretId, tagValueName); + } + + // Bind a TagValue to a Secret by creating a TagBinding. + public static TagBinding bindSecretTag(String projectId, String secretId, String tagValueName) + throws IOException, InterruptedException, ExecutionException { + + String parent = String.format("//secretmanager.googleapis.com/projects/%s/secrets/%s", + projectId, secretId); + + try (TagBindingsClient tagBindingsClient = TagBindingsClient.create()) { + TagBinding tagBinding = TagBinding.newBuilder() + .setTagValue(tagValueName) + .setParent(parent) + .build(); + + CreateTagBindingRequest request = CreateTagBindingRequest.newBuilder() + .setTagBinding(tagBinding) + .build(); + + TagBinding created = tagBindingsClient.createTagBindingAsync(request).get(); + System.out.printf("Created TagBinding: %s\n", created.getName()); + return created; + } + } +} +// [END secretmanager_bind_secret_tag] diff --git a/secretmanager/src/main/java/secretmanager/ListSecretTagBindings.java b/secretmanager/src/main/java/secretmanager/ListSecretTagBindings.java new file mode 100644 index 00000000000..2b05832e9cd --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/ListSecretTagBindings.java @@ -0,0 +1,58 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager; + +// [START secretmanager_list_secret_tag_bindings] +import com.google.cloud.resourcemanager.v3.ListTagBindingsRequest; +import com.google.cloud.resourcemanager.v3.TagBinding; +import com.google.cloud.resourcemanager.v3.TagBindingsClient; +import java.io.IOException; + +public class ListSecretTagBindings { + + public static void main(String[] args) throws Exception { + // TODO(developer): replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // This is the id of the secret to act on + String secretId = "your-secret-id"; + + listSecretTagBindings(projectId, secretId); + } + + // List tag bindings attached to the secret resource. + public static void listSecretTagBindings(String projectId, String secretId) + throws IOException { + + // Resource Manager TagBindings are listed under a parent such as the project. + String parent = String.format("//secretmanager.googleapis.com/projects/%s/secrets/%s", + projectId, secretId); + + try (TagBindingsClient tagBindingsClient = TagBindingsClient.create()) { + ListTagBindingsRequest request = + ListTagBindingsRequest.newBuilder().setParent(parent).build(); + + // Iterate over tag bindings + for (TagBinding binding : tagBindingsClient.listTagBindings(request).iterateAll()) { + System.out.printf("Found TagBinding with Name %s and TagValue %s\n", + binding.getName(), binding.getTagValue()); + } + } + } +} +// [END secretmanager_list_secret_tag_bindings] diff --git a/secretmanager/src/main/java/secretmanager/RemoveTagFromSecret.java b/secretmanager/src/main/java/secretmanager/RemoveTagFromSecret.java new file mode 100644 index 00000000000..c17527f1d8b --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/RemoveTagFromSecret.java @@ -0,0 +1,64 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager; + +// [START secretmanager_remove_tag_from_secret] +import com.google.cloud.resourcemanager.v3.ListTagBindingsRequest; +import com.google.cloud.resourcemanager.v3.TagBinding; +import com.google.cloud.resourcemanager.v3.TagBindingsClient; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class RemoveTagFromSecret { + + public static void main(String[] args) throws Exception { + // TODO(developer): replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // This is the id of the secret to act on + String secretId = "your-secret-id"; + // Tag value to remove, e.g. "tagValues/123" + String tagValueName = "your-tag-value"; + + removeTagFromSecret(projectId, secretId, tagValueName); + } + + // Remove a TagValue from a Secret by deleting the TagBinding. + public static void removeTagFromSecret(String projectId, String secretId, String tagValueName) + throws IOException, InterruptedException, ExecutionException { + + String parent = String.format("//secretmanager.googleapis.com/projects/%s/secrets/%s", + projectId, secretId); + + try (TagBindingsClient tagBindingsClient = TagBindingsClient.create()) { + ListTagBindingsRequest request = + ListTagBindingsRequest.newBuilder().setParent(parent).build(); + + // Iterate over tag bindings + for (TagBinding binding : tagBindingsClient.listTagBindings(request).iterateAll()) { + // Delete the TagBinding if it matches the specified TagValue + if (binding.getTagValue().equals(tagValueName)) { + tagBindingsClient.deleteTagBindingAsync(binding.getName()).get(); + System.out.printf("Deleted TagBinding with Name %s and TagValue %s\n", + binding.getName(), binding.getTagValue()); + } + } + } + } +} +// [END secretmanager_remove_tag_from_secret] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/BindRegionalSecretTag.java b/secretmanager/src/main/java/secretmanager/regionalsamples/BindRegionalSecretTag.java new file mode 100644 index 00000000000..50fda18f101 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/BindRegionalSecretTag.java @@ -0,0 +1,74 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager.regionalsamples; + +// [START secretmanager_bind_regional_secret_tag] +import com.google.cloud.resourcemanager.v3.CreateTagBindingRequest; +import com.google.cloud.resourcemanager.v3.TagBinding; +import com.google.cloud.resourcemanager.v3.TagBindingsClient; +import com.google.cloud.resourcemanager.v3.TagBindingsSettings; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class BindRegionalSecretTag { + + public static void main(String[] args) throws Exception { + // TODO(developer): replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // Location of the secret. + String locationId = "your-location-id"; + // This is the id of the secret to act on + String secretId = "your-secret-id"; + // Tag value to bind, e.g. "tagValues/123" + String tagValueName = "your-tag-value"; + + bindRegionalSecretTag(projectId, locationId, secretId, tagValueName); + } + + // Bind a TagValue to a regional Secret by creating a TagBinding. + public static TagBinding bindRegionalSecretTag( + String projectId, String locationId, String secretId, String tagValueName) + throws IOException, InterruptedException, ExecutionException { + + String parent = String.format( + "//secretmanager.googleapis.com/projects/%s/locations/%s/secrets/%s", + projectId, locationId, secretId); + + // Endpoint to call the regional secret manager server + String apiEndpoint = String.format("%s-cloudresourcemanager.googleapis.com:443", locationId); + TagBindingsSettings tagBindingsSettings = + TagBindingsSettings.newBuilder().setEndpoint(apiEndpoint).build(); + + try (TagBindingsClient tagBindingsClient = TagBindingsClient.create(tagBindingsSettings)) { + TagBinding tagBinding = TagBinding.newBuilder() + .setTagValue(tagValueName) + .setParent(parent) + .build(); + + CreateTagBindingRequest request = CreateTagBindingRequest.newBuilder() + .setTagBinding(tagBinding) + .build(); + + TagBinding created = tagBindingsClient.createTagBindingAsync(request).get(); + System.out.printf("Created TagBinding: %s\n", created.getName()); + return created; + } + } +} +// [END secretmanager_bind_regional_secret_tag] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/ListRegionalSecretTagBindings.java b/secretmanager/src/main/java/secretmanager/regionalsamples/ListRegionalSecretTagBindings.java new file mode 100644 index 00000000000..c853934a31e --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/ListRegionalSecretTagBindings.java @@ -0,0 +1,66 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager.regionalsamples; + +// [START secretmanager_list_regional_secret_tag_bindings] +import com.google.cloud.resourcemanager.v3.ListTagBindingsRequest; +import com.google.cloud.resourcemanager.v3.TagBinding; +import com.google.cloud.resourcemanager.v3.TagBindingsClient; +import com.google.cloud.resourcemanager.v3.TagBindingsSettings; +import java.io.IOException; + +public class ListRegionalSecretTagBindings { + + public static void main(String[] args) throws Exception { + // TODO(developer): replace these variables before running the sample. + // This is the id of the GCP project + String projectId = "your-project-id"; + // Location of the secret. + String locationId = "your-location-id"; + // This is the id of the secret to act on + String secretId = "your-secret-id"; + + listRegionalSecretTagBindings(projectId, locationId, secretId); + } + + // List tag bindings attached to the regional secret resource. + public static void listRegionalSecretTagBindings( + String projectId, String locationId, String secretId) throws IOException { + + // Resource Manager TagBindings are listed under a parent such as the project. + String parent = String.format( + "//secretmanager.googleapis.com/projects/%s/locations/%s/secrets/%s", + projectId, locationId, secretId); + + // Endpoint to call the regional secret manager server + String apiEndpoint = String.format("%s-cloudresourcemanager.googleapis.com:443", locationId); + TagBindingsSettings tagBindingsSettings = + TagBindingsSettings.newBuilder().setEndpoint(apiEndpoint).build(); + + try (TagBindingsClient tagBindingsClient = TagBindingsClient.create(tagBindingsSettings)) { + ListTagBindingsRequest request = ListTagBindingsRequest.newBuilder() + .setParent(parent).build(); + + // Iterate over tag bindings + for (TagBinding binding : tagBindingsClient.listTagBindings(request).iterateAll()) { + System.out.printf("Found TagBinding with Name %s and TagValue %s\n", + binding.getName(), binding.getTagValue()); + } + } + } +} +// [END secretmanager_list_regional_secret_tag_bindings] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/RemoveTagFromRegionalSecret.java b/secretmanager/src/main/java/secretmanager/regionalsamples/RemoveTagFromRegionalSecret.java new file mode 100644 index 00000000000..10b2cba2edb --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/RemoveTagFromRegionalSecret.java @@ -0,0 +1,74 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager.regionalsamples; + +// [START secretmanager_remove_tag_from_regionalsecret] +import com.google.cloud.resourcemanager.v3.ListTagBindingsRequest; +import com.google.cloud.resourcemanager.v3.TagBinding; +import com.google.cloud.resourcemanager.v3.TagBindingsClient; +import com.google.cloud.resourcemanager.v3.TagBindingsSettings; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class RemoveTagFromRegionalSecret { + + public static void main(String[] args) throws Exception { + // TODO(developer): replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // Location of the secret. + String locationId = "your-location-id"; + // This is the id of the secret to act on + String secretId = "your-secret-id"; + // Tag value to bind, e.g. "tagValues/123" + String tagValueName = "your-tag-value"; + + removeTagFromRegionalSecret(projectId, locationId, secretId, tagValueName); + } + + // Remove a TagValue from a regional Secret by deleting the TagBinding. + public static void removeTagFromRegionalSecret( + String projectId, String locationId, String secretId, String tagValueName) + throws IOException, InterruptedException, ExecutionException { + + String parent = String.format( + "//secretmanager.googleapis.com/projects/%s/locations/%s/secrets/%s", + projectId, locationId, secretId); + + // Endpoint to call the regional secret manager server + String apiEndpoint = String.format("%s-cloudresourcemanager.googleapis.com:443", locationId); + TagBindingsSettings tagBindingsSettings = + TagBindingsSettings.newBuilder().setEndpoint(apiEndpoint).build(); + + try (TagBindingsClient tagBindingsClient = TagBindingsClient.create(tagBindingsSettings)) { + ListTagBindingsRequest request = ListTagBindingsRequest.newBuilder() + .setParent(parent).build(); + + // Iterate over tag bindings + for (TagBinding binding : tagBindingsClient.listTagBindings(request).iterateAll()) { + // Delete the TagBinding if it matches the specified TagValue + if (binding.getTagValue().equals(tagValueName)) { + tagBindingsClient.deleteTagBindingAsync(binding.getName()).get(); + System.out.printf("Deleted TagBinding with Name %s and TagValue %s\n", + binding.getName(), binding.getTagValue()); + } + } + } + } +} +// [END secretmanager_remove_tag_from_regional_secret] diff --git a/secretmanager/src/test/java/secretmanager/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/SnippetsIT.java index fd219a3607a..a7ad69ac456 100644 --- a/secretmanager/src/test/java/secretmanager/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/SnippetsIT.java @@ -58,6 +58,7 @@ import java.util.List; import java.util.Map; import java.util.Random; +import java.util.concurrent.ExecutionException; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; @@ -572,6 +573,38 @@ public void testListSecretsWithFilter() throws IOException { assertThat(stdOut.toString()).contains(name.getSecret()); } + @Test + public void testListSecretTagBindings() throws IOException { + SecretName name = TEST_SECRET_WITH_TAGS_TO_CREATE_NAME; + ListSecretTagBindings.listSecretTagBindings(name.getProject(), name.getSecret()); + + assertThat(stdOut.toString()).contains("Found TagBinding"); + } + + @Test + public void testBindSecretTag() throws IOException, InterruptedException, ExecutionException { + SecretName name = SecretName.parse(TEST_SECRET.getName()); + BindSecretTag.bindSecretTag( + name.getProject(), + name.getSecret(), + TAG_VALUE.getName()); + + assertThat(stdOut.toString()).contains("Created TagBinding"); + } + + @Test + public void testRemoveTagFromSecret() + throws IOException, InterruptedException, ExecutionException { + + SecretName name = SecretName.parse(TEST_SECRET.getName()); + RemoveTagFromSecret.removeTagFromSecret( + name.getProject(), + name.getSecret(), + TAG_VALUE.getName()); + + assertThat(stdOut.toString()).contains("Deleted TagBinding"); + } + @Test public void testUpdateSecret() throws IOException { SecretName name = SecretName.parse(TEST_SECRET.getName()); diff --git a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java index 067a69b1e33..7488b5a4e2d 100644 --- a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java @@ -64,6 +64,7 @@ import java.lang.Exception; import java.util.Map; import java.util.Random; +import java.util.concurrent.ExecutionException; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; @@ -657,6 +658,44 @@ public void testListRegionalSecretsWithFilter() throws IOException { assertTrue(secretPresentInList); } + @Test + public void testListRegionalSecretTagBindings() throws IOException { + SecretName name = TEST_REGIONAL_SECRET_WITH_TAGS_TO_CREATE_NAME; + ListRegionalSecretTagBindings.listRegionalSecretTagBindings( + name.getProject(), name.getLocation(), name.getSecret() + ); + + assertThat(stdOut.toString()).contains("Found TagBinding"); + } + + @Test + public void testBindRegionalSecretTag() + throws IOException, InterruptedException, ExecutionException { + + SecretName name = SecretName.parse(TEST_REGIONAL_SECRET.getName()); + BindRegionalSecretTag.bindRegionalSecretTag( + name.getProject(), + name.getLocation(), + name.getSecret(), + TAG_VALUE.getName()); + + assertThat(stdOut.toString()).contains("Created TagBinding"); + } + + @Test + public void testRemoveTagFromRegionalSecret() + throws IOException, InterruptedException, ExecutionException { + + SecretName name = SecretName.parse(TEST_REGIONAL_SECRET.getName()); + RemoveTagFromRegionalSecret.removeTagFromRegionalSecret( + name.getProject(), + name.getLocation(), + name.getSecret(), + TAG_VALUE.getName()); + + assertThat(stdOut.toString()).contains("Deleted TagBinding"); + } + @Test public void testEditRegionalSecretLabel() throws IOException { SecretName name = SecretName.parse(TEST_REGIONAL_SECRET.getName()); From c3359019283ca0588d757471431e7a9719f0a438 Mon Sep 17 00:00:00 2001 From: Dhaval Bhensdadiya Date: Thu, 22 Jan 2026 12:35:15 +0530 Subject: [PATCH 7/8] Renamed files related to delete tags to match existing files --- ...RemoveTagFromSecret.java => DeleteSecretTag.java} | 12 ++++++------ ...ionalSecret.java => DeleteRegionalSecretTag.java} | 10 +++++----- .../src/test/java/secretmanager/SnippetsIT.java | 2 +- .../secretmanager/regionalsamples/SnippetsIT.java | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) rename secretmanager/src/main/java/secretmanager/{RemoveTagFromSecret.java => DeleteSecretTag.java} (86%) rename secretmanager/src/main/java/secretmanager/regionalsamples/{RemoveTagFromRegionalSecret.java => DeleteRegionalSecretTag.java} (90%) diff --git a/secretmanager/src/main/java/secretmanager/RemoveTagFromSecret.java b/secretmanager/src/main/java/secretmanager/DeleteSecretTag.java similarity index 86% rename from secretmanager/src/main/java/secretmanager/RemoveTagFromSecret.java rename to secretmanager/src/main/java/secretmanager/DeleteSecretTag.java index c17527f1d8b..0d533312ec2 100644 --- a/secretmanager/src/main/java/secretmanager/RemoveTagFromSecret.java +++ b/secretmanager/src/main/java/secretmanager/DeleteSecretTag.java @@ -16,14 +16,14 @@ package secretmanager; -// [START secretmanager_remove_tag_from_secret] +// [START secretmanager_delete_secret_tag] import com.google.cloud.resourcemanager.v3.ListTagBindingsRequest; import com.google.cloud.resourcemanager.v3.TagBinding; import com.google.cloud.resourcemanager.v3.TagBindingsClient; import java.io.IOException; import java.util.concurrent.ExecutionException; -public class RemoveTagFromSecret { +public class DeleteSecretTag { public static void main(String[] args) throws Exception { // TODO(developer): replace these variables before running the sample. @@ -32,14 +32,14 @@ public static void main(String[] args) throws Exception { String projectId = "your-project-id"; // This is the id of the secret to act on String secretId = "your-secret-id"; - // Tag value to remove, e.g. "tagValues/123" + // Tag value to delete, e.g. "tagValues/123" String tagValueName = "your-tag-value"; - removeTagFromSecret(projectId, secretId, tagValueName); + deleteSecretTag(projectId, secretId, tagValueName); } // Remove a TagValue from a Secret by deleting the TagBinding. - public static void removeTagFromSecret(String projectId, String secretId, String tagValueName) + public static void deleteSecretTag(String projectId, String secretId, String tagValueName) throws IOException, InterruptedException, ExecutionException { String parent = String.format("//secretmanager.googleapis.com/projects/%s/secrets/%s", @@ -61,4 +61,4 @@ public static void removeTagFromSecret(String projectId, String secretId, String } } } -// [END secretmanager_remove_tag_from_secret] +// [END secretmanager_delete_secret_tag] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/RemoveTagFromRegionalSecret.java b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretTag.java similarity index 90% rename from secretmanager/src/main/java/secretmanager/regionalsamples/RemoveTagFromRegionalSecret.java rename to secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretTag.java index 10b2cba2edb..d4e72dbf9b5 100644 --- a/secretmanager/src/main/java/secretmanager/regionalsamples/RemoveTagFromRegionalSecret.java +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretTag.java @@ -16,7 +16,7 @@ package secretmanager.regionalsamples; -// [START secretmanager_remove_tag_from_regionalsecret] +// [START secretmanager_delete_regional_secret_tag] import com.google.cloud.resourcemanager.v3.ListTagBindingsRequest; import com.google.cloud.resourcemanager.v3.TagBinding; import com.google.cloud.resourcemanager.v3.TagBindingsClient; @@ -24,7 +24,7 @@ import java.io.IOException; import java.util.concurrent.ExecutionException; -public class RemoveTagFromRegionalSecret { +public class DeleteRegionalSecretTag { public static void main(String[] args) throws Exception { // TODO(developer): replace these variables before running the sample. @@ -38,11 +38,11 @@ public static void main(String[] args) throws Exception { // Tag value to bind, e.g. "tagValues/123" String tagValueName = "your-tag-value"; - removeTagFromRegionalSecret(projectId, locationId, secretId, tagValueName); + deleteRegionalSecretTag(projectId, locationId, secretId, tagValueName); } // Remove a TagValue from a regional Secret by deleting the TagBinding. - public static void removeTagFromRegionalSecret( + public static void deleteRegionalSecretTag( String projectId, String locationId, String secretId, String tagValueName) throws IOException, InterruptedException, ExecutionException { @@ -71,4 +71,4 @@ public static void removeTagFromRegionalSecret( } } } -// [END secretmanager_remove_tag_from_regional_secret] +// [END secretmanager_delete_regional_secret_tag] diff --git a/secretmanager/src/test/java/secretmanager/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/SnippetsIT.java index a7ad69ac456..84b43a14189 100644 --- a/secretmanager/src/test/java/secretmanager/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/SnippetsIT.java @@ -597,7 +597,7 @@ public void testRemoveTagFromSecret() throws IOException, InterruptedException, ExecutionException { SecretName name = SecretName.parse(TEST_SECRET.getName()); - RemoveTagFromSecret.removeTagFromSecret( + DeleteSecretTag.deleteSecretTag( name.getProject(), name.getSecret(), TAG_VALUE.getName()); diff --git a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java index 7488b5a4e2d..1d9b8cc2fed 100644 --- a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java @@ -687,7 +687,7 @@ public void testRemoveTagFromRegionalSecret() throws IOException, InterruptedException, ExecutionException { SecretName name = SecretName.parse(TEST_REGIONAL_SECRET.getName()); - RemoveTagFromRegionalSecret.removeTagFromRegionalSecret( + DeleteRegionalSecretTag.deleteRegionalSecretTag( name.getProject(), name.getLocation(), name.getSecret(), From 15b8d11377cf3d653dc8d9f55f3877ebfc5a0742 Mon Sep 17 00:00:00 2001 From: Dhaval Bhensdadiya Date: Thu, 22 Jan 2026 15:17:54 +0530 Subject: [PATCH 8/8] feat(secretmanager): add examples for creating, updating and deleting secret expiration times --- .../CreateSecretWithExpiration.java | 77 ++++++++++++++++ .../secretmanager/DeleteSecretExpiration.java | 66 ++++++++++++++ .../secretmanager/UpdateSecretExpiration.java | 78 ++++++++++++++++ .../CreateRegionalSecretWithExpiration.java | 82 +++++++++++++++++ .../DeleteRegionalSecretExpiration.java | 77 ++++++++++++++++ .../UpdateRegionalSecretExpiration.java | 90 +++++++++++++++++++ .../test/java/secretmanager/SnippetsIT.java | 38 ++++++++ .../regionalsamples/SnippetsIT.java | 39 ++++++++ 8 files changed, 547 insertions(+) create mode 100644 secretmanager/src/main/java/secretmanager/CreateSecretWithExpiration.java create mode 100644 secretmanager/src/main/java/secretmanager/DeleteSecretExpiration.java create mode 100644 secretmanager/src/main/java/secretmanager/UpdateSecretExpiration.java create mode 100644 secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithExpiration.java create mode 100644 secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretExpiration.java create mode 100644 secretmanager/src/main/java/secretmanager/regionalsamples/UpdateRegionalSecretExpiration.java diff --git a/secretmanager/src/main/java/secretmanager/CreateSecretWithExpiration.java b/secretmanager/src/main/java/secretmanager/CreateSecretWithExpiration.java new file mode 100644 index 00000000000..c4472edc486 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/CreateSecretWithExpiration.java @@ -0,0 +1,77 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager; + +// [START secretmanager_create_secret_with_expiration] +import com.google.cloud.secretmanager.v1.ProjectName; +import com.google.cloud.secretmanager.v1.Replication; +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.protobuf.Timestamp; +import java.io.IOException; +import java.time.Instant; + +public class CreateSecretWithExpiration { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // This is the id of the secret to create + String secretId = "your-secret-id"; + // This is the time in seconds from now when the secret will expire + long expireTimeSeconds = 86400; // 24 hours + createSecretWithExpiration(projectId, secretId, expireTimeSeconds); + } + + // Create a new secret with an expiration time. + public static Secret createSecretWithExpiration( + String projectId, String secretId, long expireTimeSeconds) throws IOException { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) { + // Build the parent name from the project. + ProjectName projectName = ProjectName.of(projectId); + + // Calculate the expiration time. + Instant expireTime = Instant.now().plusSeconds(expireTimeSeconds); + Timestamp expireTimestamp = Timestamp.newBuilder() + .setSeconds(expireTime.getEpochSecond()) + .setNanos(expireTime.getNano()) + .build(); + + // Build the secret to create with expiration time. + Secret secret = + Secret.newBuilder() + .setReplication( + Replication.newBuilder() + .setAutomatic(Replication.Automatic.newBuilder().build()) + .build()) + .setExpireTime(expireTimestamp) + .build(); + + // Create the secret. + Secret createdSecret = client.createSecret(projectName, secretId, secret); + System.out.printf("Created secret %s with expire time\n", createdSecret.getName()); + + return createdSecret; + } + } +} +// [END secretmanager_create_secret_with_expiration] diff --git a/secretmanager/src/main/java/secretmanager/DeleteSecretExpiration.java b/secretmanager/src/main/java/secretmanager/DeleteSecretExpiration.java new file mode 100644 index 00000000000..2af3042981d --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/DeleteSecretExpiration.java @@ -0,0 +1,66 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager; + +// [START secretmanager_delete_secret_expiration] +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretName; +import com.google.protobuf.FieldMask; +import com.google.protobuf.util.FieldMaskUtil; +import java.io.IOException; + +public class DeleteSecretExpiration { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // This is the id of the secret to update + String secretId = "your-secret-id"; + deleteSecretExpiration(projectId, secretId); + } + + // Delete the expiration time from an existing secret. + public static Secret deleteSecretExpiration(String projectId, String secretId) + throws IOException { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) { + // Build the secret name. + SecretName secretName = SecretName.of(projectId, secretId); + + // Build the updated secret without expiration time. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .build(); + + // Build the field mask to clear the expiration time. + FieldMask fieldMask = FieldMaskUtil.fromString("expire_time"); + + // Update the secret to remove expiration. + Secret updatedSecret = client.updateSecret(secret, fieldMask); + System.out.printf("Deleted expiration from secret %s\n", updatedSecret.getName()); + + return updatedSecret; + } + } +} +// [END secretmanager_delete_secret_expiration] diff --git a/secretmanager/src/main/java/secretmanager/UpdateSecretExpiration.java b/secretmanager/src/main/java/secretmanager/UpdateSecretExpiration.java new file mode 100644 index 00000000000..90cae2fcef3 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/UpdateSecretExpiration.java @@ -0,0 +1,78 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager; + +// [START secretmanager_update_secret_expiration] +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretName; +import com.google.protobuf.FieldMask; +import com.google.protobuf.Timestamp; +import com.google.protobuf.util.FieldMaskUtil; +import java.io.IOException; +import java.time.Instant; + +public class UpdateSecretExpiration { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // This is the id of the GCP project + String projectId = "your-project-id"; + // This is the id of the secret to update + String secretId = "your-secret-id"; + // This is the time in seconds from now when the secret will expire + long expireTimeSeconds = 86400; // 24 hours + updateSecretExpiration(projectId, secretId, expireTimeSeconds); + } + + // Update an existing secret with a new expiration time. + public static Secret updateSecretExpiration( + String projectId, String secretId, long expireTimeSeconds) throws IOException { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. After completing all of your requests, call + // the "close" method on the client to safely clean up any remaining background resources. + try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) { + // Build the secret name. + SecretName secretName = SecretName.of(projectId, secretId); + + // Calculate the expiration time. + Instant expireTime = Instant.now().plusSeconds(expireTimeSeconds); + Timestamp expireTimestamp = Timestamp.newBuilder() + .setSeconds(expireTime.getEpochSecond()) + .setNanos(expireTime.getNano()) + .build(); + + // Build the updated secret with new expiration time. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .setExpireTime(expireTimestamp) + .build(); + + // Build the field mask to update only the expiration time. + FieldMask fieldMask = FieldMaskUtil.fromString("expire_time"); + + // Update the secret. + Secret updatedSecret = client.updateSecret(secret, fieldMask); + System.out.printf("Updated secret %s with new expiration time\n", updatedSecret.getName()); + + return updatedSecret; + } + } +} +// [END secretmanager_update_secret_expiration] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithExpiration.java b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithExpiration.java new file mode 100644 index 00000000000..bce2f5c0fb8 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithExpiration.java @@ -0,0 +1,82 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager.regionalsamples; + +// [START secretmanager_create_regional_secret_with_expiration] +import com.google.cloud.secretmanager.v1.LocationName; +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; +import com.google.protobuf.Timestamp; +import java.io.IOException; +import java.time.Instant; + +public class CreateRegionalSecretWithExpiration { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // Your GCP project ID. + String projectId = "your-project-id"; + // Location of the secret. + String locationId = "your-location-id"; + // Resource ID of the secret to create. + String secretId = "your-secret-id"; + // This is the time in seconds from now when the secret will expire. + long expireTimeSeconds = 86400; // 24 hours + createRegionalSecretWithExpiration(projectId, locationId, secretId, expireTimeSeconds); + } + + // Create a new regional secret with an expiration time. + public static Secret createRegionalSecretWithExpiration( + String projectId, String locationId, String secretId, long expireTimeSeconds) + throws IOException { + + // Endpoint to call the regional secret manager sever + String apiEndpoint = String.format("secretmanager.%s.rep.googleapis.com:443", locationId); + SecretManagerServiceSettings secretManagerServiceSettings = + SecretManagerServiceSettings.newBuilder().setEndpoint(apiEndpoint).build(); + + // Initialize the client that will be used to send requests. This client only needs to be + // created once, and can be reused for multiple requests. + try (SecretManagerServiceClient client = + SecretManagerServiceClient.create(secretManagerServiceSettings)) { + // Build the parent name from the project. + LocationName location = LocationName.of(projectId, locationId); + + // Calculate the expiration time. + Instant expireTime = Instant.now().plusSeconds(expireTimeSeconds); + Timestamp expireTimestamp = Timestamp.newBuilder() + .setSeconds(expireTime.getEpochSecond()) + .setNanos(expireTime.getNano()) + .build(); + + // Build the regional secret to create with expiration time. + Secret secret = + Secret.newBuilder() + .setExpireTime(expireTimestamp) + .build(); + + // Create the regional secret. + Secret createdSecret = client.createSecret(location.toString(), secretId, secret); + System.out.printf("Created secret %s with expire time\n", createdSecret.getName()); + + return createdSecret; + } + } +} +// [END secretmanager_create_regional_secret_with_expiration] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretExpiration.java b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretExpiration.java new file mode 100644 index 00000000000..b4bb5206103 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretExpiration.java @@ -0,0 +1,77 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager.regionalsamples; + +// [START secretmanager_delete_regional_secret_expiration] +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; +import com.google.cloud.secretmanager.v1.SecretName; +import com.google.protobuf.FieldMask; +import com.google.protobuf.util.FieldMaskUtil; +import java.io.IOException; + +public class DeleteRegionalSecretExpiration { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // Your GCP project ID. + String projectId = "your-project-id"; + // Location of the secret. + String locationId = "your-location-id"; + // Resource ID of the secret to update. + String secretId = "your-secret-id"; + deleteRegionalSecretExpiration(projectId, locationId, secretId); + } + + // Delete the expiration time from an existing regional secret. + public static Secret deleteRegionalSecretExpiration( + String projectId, String locationId, String secretId) throws IOException { + + // Endpoint to call the regional secret manager sever + String apiEndpoint = String.format("secretmanager.%s.rep.googleapis.com:443", locationId); + SecretManagerServiceSettings secretManagerServiceSettings = + SecretManagerServiceSettings.newBuilder().setEndpoint(apiEndpoint).build(); + + // Initialize the client that will be used to send requests. This client only needs to be + // created once, and can be reused for multiple requests. + try (SecretManagerServiceClient client = + SecretManagerServiceClient.create(secretManagerServiceSettings)) { + // Build the secret name. + SecretName secretName = + SecretName.ofProjectLocationSecretName(projectId, locationId, secretId); + + // Build the updated secret without expiration time. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .build(); + + // Build the field mask to clear the expiration time. + FieldMask fieldMask = FieldMaskUtil.fromString("expire_time"); + + // Update the secret to remove expiration. + Secret updatedSecret = client.updateSecret(secret, fieldMask); + System.out.printf("Deleted expiration from secret %s\n", + updatedSecret.getName()); + + return updatedSecret; + } + } +} +// [END secretmanager_delete_regional_secret_expiration] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/UpdateRegionalSecretExpiration.java b/secretmanager/src/main/java/secretmanager/regionalsamples/UpdateRegionalSecretExpiration.java new file mode 100644 index 00000000000..3e675588ecf --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/UpdateRegionalSecretExpiration.java @@ -0,0 +1,90 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package secretmanager.regionalsamples; + +// [START secretmanager_update_regional_secret_expiration] +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretManagerServiceSettings; +import com.google.cloud.secretmanager.v1.SecretName; +import com.google.protobuf.FieldMask; +import com.google.protobuf.Timestamp; +import com.google.protobuf.util.FieldMaskUtil; +import java.io.IOException; +import java.time.Instant; + +public class UpdateRegionalSecretExpiration { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + + // Your GCP project ID. + String projectId = "your-project-id"; + // Location of the secret. + String locationId = "your-location-id"; + // Resource ID of the secret to update. + String secretId = "your-secret-id"; + // This is the time in seconds from now when the secret will expire. + long expireTimeSeconds = 86400; // 24 hours + updateRegionalSecretExpiration(projectId, locationId, secretId, expireTimeSeconds); + } + + // Update an existing regional secret with a new expiration time. + public static Secret updateRegionalSecretExpiration( + String projectId, String locationId, String secretId, long expireTimeSeconds) + throws IOException { + + // Endpoint to call the regional secret manager sever + String apiEndpoint = String.format("secretmanager.%s.rep.googleapis.com:443", locationId); + SecretManagerServiceSettings secretManagerServiceSettings = + SecretManagerServiceSettings.newBuilder().setEndpoint(apiEndpoint).build(); + + // Initialize the client that will be used to send requests. This client only needs to be + // created once, and can be reused for multiple requests. + try (SecretManagerServiceClient client = + SecretManagerServiceClient.create(secretManagerServiceSettings)) { + // Build the secret name. + SecretName secretName = + SecretName.ofProjectLocationSecretName(projectId, locationId, secretId); + + // Calculate the expiration time. + Instant expireTime = Instant.now().plusSeconds(expireTimeSeconds); + Timestamp expireTimestamp = Timestamp.newBuilder() + .setSeconds(expireTime.getEpochSecond()) + .setNanos(expireTime.getNano()) + .build(); + + // Build the updated secret with new expiration time. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .setExpireTime(expireTimestamp) + .build(); + + // Build the field mask to update only the expiration time. + FieldMask fieldMask = FieldMaskUtil.fromString("expire_time"); + + // Update the secret. + Secret updatedSecret = client.updateSecret(secret, fieldMask); + System.out.printf("Updated secret %s with new expiration time\n", + updatedSecret.getName()); + + return updatedSecret; + } + } +} +// [END secretmanager_update_regional_secret_expiration] diff --git a/secretmanager/src/test/java/secretmanager/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/SnippetsIT.java index 84b43a14189..c50e0eb62b8 100644 --- a/secretmanager/src/test/java/secretmanager/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/SnippetsIT.java @@ -96,7 +96,9 @@ public class SnippetsIT { private static Secret TEST_SECRET_TO_DELETE_ANNOTATIONS; private static Secret TEST_SECRET_TO_DELAYED_DESTROY; private static Secret TEST_SECRET_WITH_VERSIONS; + private static Secret TEST_SECRET_WITH_EXPIRATION; private static SecretName TEST_SECRET_WITH_DELAYED_DESTROY; + private static SecretName TEST_SECRET_WITH_EXPIRATION_TO_CREATE_NAME; private static SecretName TEST_SECRET_TO_CREATE_NAME; private static SecretName TEST_SECRET_WITH_LABEL_TO_CREATE_NAME; private static SecretName TEST_SECRET_WITH_TAGS_TO_CREATE_NAME; @@ -134,6 +136,8 @@ public static void beforeAll() throws Exception { TEST_SECRET_WITH_LABEL_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); TEST_SECRET_WITH_ANNOTATION_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); TEST_SECRET_WITH_CMEK_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); + TEST_SECRET_WITH_EXPIRATION_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); + TEST_SECRET_WITH_EXPIRATION = createSecret(false); TEST_SECRET_VERSION = addSecretVersion(TEST_SECRET_WITH_VERSIONS); TEST_SECRET_VERSION_TO_DESTROY = addSecretVersion(TEST_SECRET_WITH_VERSIONS); @@ -176,6 +180,8 @@ public static void afterAll() throws Exception { deleteSecret(TEST_SECRET_WITH_VERSIONS.getName()); deleteSecret(TEST_SECRET_WITH_DELAYED_DESTROY.toString()); deleteSecret(TEST_SECRET_TO_DELAYED_DESTROY.getName()); + deleteSecret(TEST_SECRET_WITH_EXPIRATION_TO_CREATE_NAME.toString()); + deleteSecret(TEST_SECRET_WITH_EXPIRATION.getName()); deleteTags(); } @@ -696,4 +702,36 @@ public void testConsumeEventNotification() { assertThat(log).isEqualTo( "Received SECRET_UPDATE for projects/p/secrets/s. New metadata: hello!"); } + + @Test + public void testCreateSecretWithExpiration() throws IOException { + SecretName name = TEST_SECRET_WITH_EXPIRATION_TO_CREATE_NAME; + Secret secret = CreateSecretWithExpiration.createSecretWithExpiration( + name.getProject(), name.getSecret(), 86400); + + assertThat(stdOut.toString()).contains("Created secret"); + assertThat(stdOut.toString()).contains("with expire time"); + assertThat(secret.hasExpireTime()).isTrue(); + } + + @Test + public void testUpdateSecretExpiration() throws IOException { + SecretName name = SecretName.parse(TEST_SECRET_WITH_EXPIRATION.getName()); + Secret secret = UpdateSecretExpiration.updateSecretExpiration( + name.getProject(), name.getSecret(), 172800); + + assertThat(stdOut.toString()).contains("Updated secret"); + assertThat(stdOut.toString()).contains("with new expiration time"); + assertThat(secret.hasExpireTime()).isTrue(); + } + + @Test + public void testDeleteSecretExpiration() throws IOException { + SecretName name = SecretName.parse(TEST_SECRET_WITH_EXPIRATION.getName()); + Secret secret = DeleteSecretExpiration.deleteSecretExpiration( + name.getProject(), name.getSecret()); + + assertThat(stdOut.toString()).contains("Deleted expiration from secret"); + assertThat(secret.hasExpireTime()).isFalse(); + } } diff --git a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java index 1d9b8cc2fed..0a20ebe4941 100644 --- a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java +++ b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java @@ -104,7 +104,9 @@ public class SnippetsIT { private static Secret TEST_REGIONAL_SECRET_TO_DELETE_ANNOTATIONS; private static Secret TEST_REGIONAL_SECRET_WITH_VERSIONS; private static Secret TEST_REGIONAL_SECRET_TO_DELAYED_DESTROY; + private static Secret TEST_REGIONAL_SECRET_WITH_EXPIRATION; private static SecretName TEST_REGIONAL_SECRET_WITH_DELAYED_DESTROY; + private static SecretName TEST_REGIONAL_SECRET_WITH_EXPIRATION_TO_CREATE_NAME; private static SecretName TEST_REGIONAL_SECRET_TO_CREATE_NAME; private static SecretName TEST_REGIONAL_SECRET_WITH_LABEL_TO_CREATE_NAME; private static SecretName TEST_REGIONAL_SECRET_WITH_TAGS_TO_CREATE_NAME; @@ -150,6 +152,9 @@ public static void beforeAll() throws Exception { SecretName.ofProjectLocationSecretName(PROJECT_ID, LOCATION_ID, randomSecretId()); TEST_REGIONAL_SECRET_WITH_TAGS_TO_CREATE_NAME = SecretName.ofProjectLocationSecretName(PROJECT_ID, LOCATION_ID, randomSecretId()); + TEST_REGIONAL_SECRET_WITH_EXPIRATION_TO_CREATE_NAME = + SecretName.ofProjectLocationSecretName(PROJECT_ID, LOCATION_ID, randomSecretId()); + TEST_REGIONAL_SECRET_WITH_EXPIRATION = createRegionalSecret(); TEST_REGIONAL_SECRET_VERSION = addRegionalSecretVersion(TEST_REGIONAL_SECRET_WITH_VERSIONS); TEST_REGIONAL_SECRET_VERSION_TO_DESTROY = addRegionalSecretVersion(TEST_REGIONAL_SECRET_WITH_VERSIONS); @@ -197,6 +202,8 @@ public static void afterAll() throws Exception { deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_VERSIONS.getName()); deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_DELAYED_DESTROY.toString()); deleteRegionalSecret(TEST_REGIONAL_SECRET_TO_DELAYED_DESTROY.getName()); + deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_EXPIRATION_TO_CREATE_NAME.toString()); + deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_EXPIRATION.getName()); deleteTags(); } @@ -782,5 +789,37 @@ public void testDisableRegionalSecretDelayedDestroy() throws IOException { assertThat(stdOut.toString()).contains("Updated secret"); assertThat(secret.getVersionDestroyTtl().getSeconds()).isEqualTo(0); } + + @Test + public void testCreateRegionalSecretWithExpiration() throws IOException { + SecretName name = TEST_REGIONAL_SECRET_WITH_EXPIRATION_TO_CREATE_NAME; + Secret secret = CreateRegionalSecretWithExpiration.createRegionalSecretWithExpiration( + name.getProject(), name.getLocation(), name.getSecret(), 86400); + + assertThat(stdOut.toString()).contains("Created secret"); + assertThat(stdOut.toString()).contains("with expire time"); + assertThat(secret.hasExpireTime()).isTrue(); + } + + @Test + public void testUpdateRegionalSecretExpiration() throws IOException { + SecretName name = SecretName.parse(TEST_REGIONAL_SECRET_WITH_EXPIRATION.getName()); + Secret secret = UpdateRegionalSecretExpiration.updateRegionalSecretExpiration( + name.getProject(), name.getLocation(), name.getSecret(), 172800); + + assertThat(stdOut.toString()).contains("Updated secret"); + assertThat(stdOut.toString()).contains("with new expiration time"); + assertThat(secret.hasExpireTime()).isTrue(); + } + + @Test + public void testDeleteRegionalSecretExpiration() throws IOException { + SecretName name = SecretName.parse(TEST_REGIONAL_SECRET_WITH_EXPIRATION.getName()); + Secret secret = DeleteRegionalSecretExpiration.deleteRegionalSecretExpiration( + name.getProject(), name.getLocation(), name.getSecret()); + + assertThat(stdOut.toString()).contains("Deleted expiration from secret"); + assertThat(secret.hasExpireTime()).isFalse(); + } }