diff --git a/secretmanager/README.md b/secretmanager/README.md index 0af70bfd6bf..417d7d3e76f 100644 --- a/secretmanager/README.md +++ b/secretmanager/README.md @@ -12,21 +12,28 @@ 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), [Cloud KMS API](https://console.cloud.google.com/flows/enableapi?apiid=cloudkms.googleapis.com) and [Pub/Sub API](https://console.cloud.google.com/flows/enableapi?apiid=pubsub.googleapis.com) for your project in order to use these samples ### 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), and Pub/Sub Topic 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= +$ export GOOGLE_CLOUD_PUBSUB_TOPIC= ``` +The Pub/Sub topic should be in the format `projects/PROJECT_ID/topics/TOPIC_ID` and is used for testing secret notifications. + ### Grant Permissions You must ensure that the [user account or service account](https://cloud.google.com/iam/docs/service-accounts#differences_between_a_service_account_and_a_user_account) you used to authorize your gcloud session has the proper permissions to edit Secret Manager resources for your project. In the Cloud Console under IAM, add the following roles to the project whose service account you're using to test: * 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 +* Pub/Sub Publisher (`roles/pubsub.publisher`) on the Pub/Sub topic 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/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/CreateSecretWithCmek.java b/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.java new file mode 100644 index 00000000000..4029b1f79ee --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/CreateSecretWithCmek.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; + +// [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; +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(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 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 a customer-managed encryption key (CMEK). + 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 the replication policy. + 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_cmek] 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/CreateSecretWithRotation.java b/secretmanager/src/main/java/secretmanager/CreateSecretWithRotation.java new file mode 100644 index 00000000000..9f7ed03f2ee --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/CreateSecretWithRotation.java @@ -0,0 +1,95 @@ +/* + * 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_rotation] +import com.google.cloud.secretmanager.v1.ProjectName; +import com.google.cloud.secretmanager.v1.Replication; +import com.google.cloud.secretmanager.v1.Rotation; +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.Topic; +import com.google.protobuf.Duration; +import com.google.protobuf.Timestamp; +import java.io.IOException; +import java.time.Instant; + +public class CreateSecretWithRotation { + + 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 rotation period in seconds (e.g., 2592000 for 30 days) + long rotationPeriodSeconds = 2592000; + // This is the topic name in the format projects/PROJECT_ID/topics/TOPIC_ID + String topicName = "projects/your-project-id/topics/your-topic-id"; + createSecretWithRotation(projectId, secretId, rotationPeriodSeconds, topicName); + } + + // Create a new secret with automatic rotation. + public static Secret createSecretWithRotation( + String projectId, String secretId, long rotationPeriodSeconds, String topicName) + 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 next rotation time. + Instant nextRotationTime = Instant.now().plusSeconds(rotationPeriodSeconds); + Timestamp nextRotationTimestamp = Timestamp.newBuilder() + .setSeconds(nextRotationTime.getEpochSecond()) + .setNanos(nextRotationTime.getNano()) + .build(); + + // Build the rotation policy. + Rotation rotation = Rotation.newBuilder() + .setNextRotationTime(nextRotationTimestamp) + .setRotationPeriod(Duration.newBuilder().setSeconds(rotationPeriodSeconds).build()) + .build(); + + // Build the topic for rotation notifications. + Topic topic = Topic.newBuilder() + .setName(topicName) + .build(); + + // Build the secret to create with rotation and topic. + Secret secret = + Secret.newBuilder() + .setReplication( + Replication.newBuilder() + .setAutomatic(Replication.Automatic.newBuilder().build()) + .build()) + .setRotation(rotation) + .addTopics(topic) + .build(); + + // Create the secret. + Secret createdSecret = client.createSecret(projectName, secretId, secret); + System.out.printf("Created secret %s with rotation\n", createdSecret.getName()); + + return createdSecret; + } + } +} +// [END secretmanager_create_secret_with_rotation] diff --git a/secretmanager/src/main/java/secretmanager/CreateSecretWithTopic.java b/secretmanager/src/main/java/secretmanager/CreateSecretWithTopic.java new file mode 100644 index 00000000000..8fd32268cff --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/CreateSecretWithTopic.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; + +// [START secretmanager_create_secret_with_topic] +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.cloud.secretmanager.v1.Topic; +import java.io.IOException; + +public class CreateSecretWithTopic { + + 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 topic name in the format projects/PROJECT_ID/topics/TOPIC_ID + String topicName = "projects/your-project-id/topics/your-topic-id"; + createSecretWithTopic(projectId, secretId, topicName); + } + + // Create a new secret with a Pub/Sub topic for notifications. + public static Secret createSecretWithTopic( + String projectId, String secretId, String topicName) 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); + + // Build the topic. + Topic topic = Topic.newBuilder() + .setName(topicName) + .build(); + + // Build the secret to create with topic. + Secret secret = + Secret.newBuilder() + .setReplication( + Replication.newBuilder() + .setAutomatic(Replication.Automatic.newBuilder().build()) + .build()) + .addTopics(topic) + .build(); + + // Create the secret. + Secret createdSecret = client.createSecret(projectName, secretId, secret); + System.out.printf("Created secret %s with topic\n", createdSecret.getName()); + + return createdSecret; + } + } +} +// [END secretmanager_create_secret_with_topic] diff --git a/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java b/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java new file mode 100644 index 00000000000..c689d1bc813 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/DeleteSecretAnnotations.java @@ -0,0 +1,69 @@ +/* + * 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; + +public class DeleteSecretAnnotations { + + + 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 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); + + // Build the updated secret with an empty annotations map. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .putAllAnnotations(new HashMap<>()) + .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/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/DeleteSecretRotation.java b/secretmanager/src/main/java/secretmanager/DeleteSecretRotation.java new file mode 100644 index 00000000000..91a4f1d415d --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/DeleteSecretRotation.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_rotation] +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 DeleteSecretRotation { + + 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"; + deleteSecretRotation(projectId, secretId); + } + + // Delete the rotation policy from an existing secret. + public static Secret deleteSecretRotation(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 rotation. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .build(); + + // Build the field mask to clear the rotation. + FieldMask fieldMask = FieldMaskUtil.fromString("rotation"); + + // Update the secret to remove rotation. + Secret updatedSecret = client.updateSecret(secret, fieldMask); + System.out.printf("Deleted rotation from secret %s\n", updatedSecret.getName()); + + return updatedSecret; + } + } +} +// [END secretmanager_delete_secret_rotation] diff --git a/secretmanager/src/main/java/secretmanager/DeleteSecretTag.java b/secretmanager/src/main/java/secretmanager/DeleteSecretTag.java new file mode 100644 index 00000000000..0d533312ec2 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/DeleteSecretTag.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_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 DeleteSecretTag { + + 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 delete, e.g. "tagValues/123" + String tagValueName = "your-tag-value"; + + deleteSecretTag(projectId, secretId, tagValueName); + } + + // Remove a TagValue from a Secret by deleting the TagBinding. + 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", + 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_delete_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/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/UpdateSecretRotation.java b/secretmanager/src/main/java/secretmanager/UpdateSecretRotation.java new file mode 100644 index 00000000000..34554aedf23 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/UpdateSecretRotation.java @@ -0,0 +1,96 @@ +/* + * 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_rotation] +import com.google.cloud.secretmanager.v1.Rotation; +import com.google.cloud.secretmanager.v1.Secret; +import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; +import com.google.cloud.secretmanager.v1.SecretName; +import com.google.cloud.secretmanager.v1.Topic; +import com.google.protobuf.Duration; +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 UpdateSecretRotation { + + 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 rotation period in seconds (e.g., 2592000 for 30 days) + long rotationPeriodSeconds = 2592000; + // This is the topic name in the format projects/PROJECT_ID/topics/TOPIC_ID + String topicName = "projects/your-project-id/topics/your-topic-id"; + updateSecretRotation(projectId, secretId, rotationPeriodSeconds, topicName); + } + + // Update an existing secret with a new rotation policy. + public static Secret updateSecretRotation( + String projectId, String secretId, long rotationPeriodSeconds, String topicName) + 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 next rotation time. + Instant nextRotationTime = Instant.now().plusSeconds(rotationPeriodSeconds); + Timestamp nextRotationTimestamp = Timestamp.newBuilder() + .setSeconds(nextRotationTime.getEpochSecond()) + .setNanos(nextRotationTime.getNano()) + .build(); + + // Build the rotation policy. + Rotation rotation = Rotation.newBuilder() + .setNextRotationTime(nextRotationTimestamp) + .setRotationPeriod(Duration.newBuilder().setSeconds(rotationPeriodSeconds).build()) + .build(); + + // Build the topic for rotation notifications. + Topic topic = Topic.newBuilder() + .setName(topicName) + .build(); + + // Build the updated secret with new rotation policy and topic. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .setRotation(rotation) + .addTopics(topic) + .build(); + + // Build the field mask to update rotation and topics. + FieldMask fieldMask = FieldMaskUtil.fromString("rotation,topics"); + + // Update the secret. + Secret updatedSecret = client.updateSecret(secret, fieldMask); + System.out.printf("Updated secret %s with new rotation policy\n", updatedSecret.getName()); + + return updatedSecret; + } + } +} +// [END secretmanager_update_secret_rotation] 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/CreateRegionalSecretWithCmek.java b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithCmek.java new file mode 100644 index 00000000000..9fe6928bda5 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithCmek.java @@ -0,0 +1,73 @@ +/* + * 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(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"; + // 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 + // once, and can be reused for multiple requests. + 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/CreateRegionalSecretWithExpiration.java b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithExpiration.java new file mode 100644 index 00000000000..f1395bb1e8d --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithExpiration.java @@ -0,0 +1,81 @@ +/* + * 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 = + // created once, and can be reused for multiple requests. + // 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/CreateRegionalSecretWithRotation.java b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithRotation.java new file mode 100644 index 00000000000..95e75a4a47d --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithRotation.java @@ -0,0 +1,100 @@ +/* + * 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_rotation] +import com.google.cloud.secretmanager.v1.LocationName; +import com.google.cloud.secretmanager.v1.Rotation; +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.Topic; +import com.google.protobuf.Duration; +import com.google.protobuf.Timestamp; +import java.io.IOException; +import java.time.Instant; + +public class CreateRegionalSecretWithRotation { + + 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 rotation period in seconds (e.g., 2592000 for 30 days). + long rotationPeriodSeconds = 2592000; + // This is the topic name in the format projects/PROJECT_ID/topics/TOPIC_ID. + String topicName = "projects/your-project-id/topics/your-topic-id"; + createRegionalSecretWithRotation(projectId, locationId, secretId, rotationPeriodSeconds, + topicName); + } + + // Create a new regional secret with automatic rotation. + public static Secret createRegionalSecretWithRotation( + String projectId, String locationId, String secretId, long rotationPeriodSeconds, + String topicName) 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 next rotation time. + Instant nextRotationTime = Instant.now().plusSeconds(rotationPeriodSeconds); + Timestamp nextRotationTimestamp = Timestamp.newBuilder() + .setSeconds(nextRotationTime.getEpochSecond()) + .setNanos(nextRotationTime.getNano()) + .build(); + + // Build the rotation policy. + Rotation rotation = Rotation.newBuilder() + .setNextRotationTime(nextRotationTimestamp) + .setRotationPeriod(Duration.newBuilder().setSeconds(rotationPeriodSeconds).build()) + .build(); + + // Build the topic for rotation notifications. + Topic topic = Topic.newBuilder() + .setName(topicName) + .build(); + + // Build the regional secret to create with rotation and topic. + Secret secret = + Secret.newBuilder() + .setRotation(rotation) + .addTopics(topic) + .build(); + + // Create the regional secret. + Secret createdSecret = client.createSecret(location.toString(), secretId, secret); + System.out.printf("Created secret %s with rotation\n", createdSecret.getName()); + + return createdSecret; + } + } +} +// [END secretmanager_create_regional_secret_with_rotation] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithTopic.java b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithTopic.java new file mode 100644 index 00000000000..ab9548fd010 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/CreateRegionalSecretWithTopic.java @@ -0,0 +1,79 @@ +/* + * 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_topic] +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.cloud.secretmanager.v1.Topic; +import java.io.IOException; + +public class CreateRegionalSecretWithTopic { + + 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 topic name in the format projects/PROJECT_ID/topics/TOPIC_ID. + String topicName = "projects/your-project-id/topics/your-topic-id"; + createRegionalSecretWithTopic(projectId, locationId, secretId, topicName); + } + + // Create a new regional secret with a Pub/Sub topic for notifications. + public static Secret createRegionalSecretWithTopic( + String projectId, String locationId, String secretId, String topicName) + 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); + + // Build the topic. + Topic topic = Topic.newBuilder() + .setName(topicName) + .build(); + + // Build the regional secret to create with topic. + Secret secret = + Secret.newBuilder() + .addTopics(topic) + .build(); + + // Create the regional secret. + Secret createdSecret = client.createSecret(location.toString(), secretId, secret); + System.out.printf("Created secret %s with topic\n", createdSecret.getName()); + + return createdSecret; + } + } +} +// [END secretmanager_create_regional_secret_with_topic] 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..e56bc8a6f87 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretAnnotations.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_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; + +public class DeleteRegionalSecretAnnotations { + + 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"; + // 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 + // once, and can be reused for multiple requests. + SecretManagerServiceClient.create(secretManagerServiceSettings)) { + // Build the name of the secret. + SecretName secretName = + SecretName.ofProjectLocationSecretName(projectId, locationId, secretId); + + // Build the updated secret with an empty annotations map. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .putAllAnnotations(new HashMap<>()) + .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/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/DeleteRegionalSecretRotation.java b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretRotation.java new file mode 100644 index 00000000000..471469998c2 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretRotation.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_rotation] +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 DeleteRegionalSecretRotation { + + 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"; + deleteRegionalSecretRotation(projectId, locationId, secretId); + } + + // Delete the rotation policy from an existing regional secret. + public static Secret deleteRegionalSecretRotation( + 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 rotation. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .build(); + + // Build the field mask to clear the rotation. + FieldMask fieldMask = FieldMaskUtil.fromString("rotation"); + + // Update the secret to remove rotation. + Secret updatedSecret = client.updateSecret(secret, fieldMask); + System.out.printf("Deleted rotation from secret %s\n", + updatedSecret.getName()); + + return updatedSecret; + } + } +} +// [END secretmanager_delete_regional_secret_rotation] diff --git a/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretTag.java b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretTag.java new file mode 100644 index 00000000000..d4e72dbf9b5 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/DeleteRegionalSecretTag.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_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; +import com.google.cloud.resourcemanager.v3.TagBindingsSettings; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class DeleteRegionalSecretTag { + + 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"; + + deleteRegionalSecretTag(projectId, locationId, secretId, tagValueName); + } + + // Remove a TagValue from a regional Secret by deleting the TagBinding. + public static void deleteRegionalSecretTag( + 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_delete_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/UpdateRegionalSecretExpiration.java b/secretmanager/src/main/java/secretmanager/regionalsamples/UpdateRegionalSecretExpiration.java new file mode 100644 index 00000000000..62244dd7d38 --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/UpdateRegionalSecretExpiration.java @@ -0,0 +1,89 @@ +/* + * 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(); + // created once, and can be reused for multiple requests. + // 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/main/java/secretmanager/regionalsamples/UpdateRegionalSecretRotation.java b/secretmanager/src/main/java/secretmanager/regionalsamples/UpdateRegionalSecretRotation.java new file mode 100644 index 00000000000..afc0417ad6d --- /dev/null +++ b/secretmanager/src/main/java/secretmanager/regionalsamples/UpdateRegionalSecretRotation.java @@ -0,0 +1,108 @@ +/* + * 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_rotation] +import com.google.cloud.secretmanager.v1.Rotation; +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.cloud.secretmanager.v1.Topic; +import com.google.protobuf.Duration; +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 UpdateRegionalSecretRotation { + + 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 rotation period in seconds (e.g., 2592000 for 30 days). + long rotationPeriodSeconds = 2592000; + // This is the topic name in the format projects/PROJECT_ID/topics/TOPIC_ID. + String topicName = "projects/your-project-id/topics/your-topic-id"; + updateRegionalSecretRotation(projectId, locationId, secretId, rotationPeriodSeconds, + topicName); + } + + // Update an existing regional secret with a new rotation policy. + public static Secret updateRegionalSecretRotation( + String projectId, String locationId, String secretId, long rotationPeriodSeconds, + String topicName) 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 next rotation time. + Instant nextRotationTime = Instant.now().plusSeconds(rotationPeriodSeconds); + Timestamp nextRotationTimestamp = Timestamp.newBuilder() + .setSeconds(nextRotationTime.getEpochSecond()) + .setNanos(nextRotationTime.getNano()) + .build(); + + // Build the rotation policy. + Rotation rotation = Rotation.newBuilder() + .setNextRotationTime(nextRotationTimestamp) + .setRotationPeriod(Duration.newBuilder().setSeconds(rotationPeriodSeconds).build()) + .build(); + + // Build the topic for rotation notifications. + Topic topic = Topic.newBuilder() + .setName(topicName) + .build(); + + // Build the updated secret with new rotation policy and topic. + Secret secret = + Secret.newBuilder() + .setName(secretName.toString()) + .setRotation(rotation) + .addTopics(topic) + .build(); + + // Build the field mask to update rotation and topics. + FieldMask fieldMask = FieldMaskUtil.fromString("rotation,topics"); + + // Update the secret. + Secret updatedSecret = client.updateSecret(secret, fieldMask); + System.out.printf("Updated secret %s with new rotation policy\n", + updatedSecret.getName()); + + return updatedSecret; + } + } +} +// [END secretmanager_update_regional_secret_rotation] diff --git a/secretmanager/src/test/java/secretmanager/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/SnippetsIT.java index 41f88a1e6d9..193b623acdb 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; @@ -57,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; @@ -77,6 +79,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 KMS_KEY_NAME = System.getenv("GOOGLE_CLOUD_KMS_KEY"); + private static final String PUBSUB_TOPIC_NAME = System.getenv("GOOGLE_CLOUD_PUBSUB_TOPIC"); private static final String LABEL_KEY = "examplelabelkey"; private static final String LABEL_VALUE = "examplelabelvalue"; private static final String UPDATED_LABEL_KEY = "updatedlabelkey"; @@ -89,13 +93,20 @@ 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 Secret TEST_SECRET_WITH_EXPIRATION; + private static Secret TEST_SECRET_WITH_ROTATION; private static SecretName TEST_SECRET_WITH_DELAYED_DESTROY; + private static SecretName TEST_SECRET_WITH_EXPIRATION_TO_CREATE_NAME; + private static SecretName TEST_SECRET_WITH_ROTATION_TO_CREATE_NAME; + private static SecretName TEST_SECRET_WITH_TOPIC_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; 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; @@ -113,10 +124,14 @@ 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)); + Assert.assertFalse( + "missing GOOGLE_CLOUD_PUBSUB_TOPIC", Strings.isNullOrEmpty(PUBSUB_TOPIC_NAME)); 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()); @@ -125,6 +140,12 @@ 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_WITH_EXPIRATION_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); + TEST_SECRET_WITH_ROTATION_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); + TEST_SECRET_WITH_TOPIC_TO_CREATE_NAME = SecretName.of(PROJECT_ID, randomSecretId()); + TEST_SECRET_WITH_EXPIRATION = createSecret(false); + TEST_SECRET_WITH_ROTATION = createSecret(false); TEST_SECRET_VERSION = addSecretVersion(TEST_SECRET_WITH_VERSIONS); TEST_SECRET_VERSION_TO_DESTROY = addSecretVersion(TEST_SECRET_WITH_VERSIONS); @@ -153,19 +174,25 @@ public void afterEach() { @AfterClass public static void afterAll() throws Exception { - Assert.assertFalse("missing GOOGLE_CLOUD_PROJECT", Strings.isNullOrEmpty(PROJECT_ID)); 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()); + 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()); + deleteSecret(TEST_SECRET_WITH_EXPIRATION_TO_CREATE_NAME.toString()); + deleteSecret(TEST_SECRET_WITH_EXPIRATION.getName()); + deleteSecret(TEST_SECRET_WITH_ROTATION_TO_CREATE_NAME.toString()); + deleteSecret(TEST_SECRET_WITH_ROTATION.getName()); + deleteSecret(TEST_SECRET_WITH_TOPIC_TO_CREATE_NAME.toString()); deleteTags(); } @@ -367,6 +394,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; @@ -553,6 +590,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()); + DeleteSecretTag.deleteSecretTag( + 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()); @@ -581,6 +650,15 @@ public void testEditSecretAnnotations() throws IOException { UPDATED_ANNOTATION_KEY, UPDATED_ANNOTATION_VALUE); } + @Test + public void testDeleteSecretAnnotations() throws IOException { + SecretName name = SecretName.parse(TEST_SECRET_TO_DELETE_ANNOTATIONS.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()); @@ -635,4 +713,81 @@ 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(); + } + + @Test + public void testCreateSecretWithRotation() throws IOException { + SecretName name = TEST_SECRET_WITH_ROTATION_TO_CREATE_NAME; + Secret secret = CreateSecretWithRotation.createSecretWithRotation( + name.getProject(), name.getSecret(), 2592000, PUBSUB_TOPIC_NAME); + + assertThat(stdOut.toString()).contains("Created secret"); + assertThat(stdOut.toString()).contains("with rotation"); + assertThat(secret.hasRotation()).isTrue(); + assertThat(secret.getTopicsCount()).isGreaterThan(0); + } + + @Test + public void testUpdateSecretRotation() throws IOException { + SecretName name = SecretName.parse(TEST_SECRET_WITH_ROTATION.getName()); + Secret secret = UpdateSecretRotation.updateSecretRotation( + name.getProject(), name.getSecret(), 3600000, PUBSUB_TOPIC_NAME); + + assertThat(stdOut.toString()).contains("Updated secret"); + assertThat(stdOut.toString()).contains("with new rotation policy"); + assertThat(secret.hasRotation()).isTrue(); + assertThat(secret.getTopicsCount()).isGreaterThan(0); + } + + @Test + public void testDeleteSecretRotation() throws IOException { + SecretName name = SecretName.parse(TEST_SECRET_WITH_ROTATION.getName()); + Secret secret = DeleteSecretRotation.deleteSecretRotation( + name.getProject(), name.getSecret()); + + assertThat(stdOut.toString()).contains("Deleted rotation from secret"); + assertThat(secret.hasRotation()).isFalse(); + } + + @Test + public void testCreateSecretWithTopic() throws IOException { + SecretName name = TEST_SECRET_WITH_TOPIC_TO_CREATE_NAME; + Secret secret = CreateSecretWithTopic.createSecretWithTopic( + name.getProject(), name.getSecret(), PUBSUB_TOPIC_NAME); + + assertThat(stdOut.toString()).contains("Created secret"); + assertThat(stdOut.toString()).contains("with topic"); + assertThat(secret.getTopicsCount()).isGreaterThan(0); + } } diff --git a/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java b/secretmanager/src/test/java/secretmanager/regionalsamples/SnippetsIT.java index 11ca876dc30..c9a9239f628 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; @@ -83,6 +84,9 @@ 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 PUBSUB_TOPIC_NAME = System.getenv("GOOGLE_CLOUD_PUBSUB_TOPIC"); private static final String LABEL_KEY = "examplelabelkey"; private static final String LABEL_VALUE = "examplelabelvalue"; private static final String UPDATED_LABEL_KEY = "updatedlabelkey"; @@ -98,13 +102,20 @@ 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 Secret TEST_REGIONAL_SECRET_WITH_EXPIRATION; + private static Secret TEST_REGIONAL_SECRET_WITH_ROTATION; 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_WITH_ROTATION_TO_CREATE_NAME; + private static SecretName TEST_REGIONAL_SECRET_WITH_TOPIC_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; 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,10 +134,15 @@ 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)); + Assert.assertFalse("missing GOOGLE_CLOUD_PUBSUB_TOPIC", + Strings.isNullOrEmpty(PUBSUB_TOPIC_NAME)); 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 = @@ -135,11 +151,21 @@ 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()); 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_ROTATION_TO_CREATE_NAME = + SecretName.ofProjectLocationSecretName(PROJECT_ID, LOCATION_ID, randomSecretId()); + TEST_REGIONAL_SECRET_WITH_TOPIC_TO_CREATE_NAME = + SecretName.ofProjectLocationSecretName(PROJECT_ID, LOCATION_ID, randomSecretId()); + TEST_REGIONAL_SECRET_WITH_EXPIRATION = createRegionalSecret(); + TEST_REGIONAL_SECRET_WITH_ROTATION = createRegionalSecret(); TEST_REGIONAL_SECRET_VERSION = addRegionalSecretVersion(TEST_REGIONAL_SECRET_WITH_VERSIONS); TEST_REGIONAL_SECRET_VERSION_TO_DESTROY = addRegionalSecretVersion(TEST_REGIONAL_SECRET_WITH_VERSIONS); @@ -180,11 +206,18 @@ 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_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()); + deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_EXPIRATION_TO_CREATE_NAME.toString()); + deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_EXPIRATION.getName()); + deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_ROTATION_TO_CREATE_NAME.toString()); + deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_ROTATION.getName()); + deleteRegionalSecret(TEST_REGIONAL_SECRET_WITH_TOPIC_TO_CREATE_NAME.toString()); deleteTags(); } @@ -398,6 +431,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()); @@ -635,6 +679,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()); + DeleteRegionalSecretTag.deleteRegionalSecretTag( + 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()); @@ -682,6 +764,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_TO_DELETE_ANNOTATIONS.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; @@ -711,5 +803,82 @@ 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(); + } + + @Test + public void testCreateRegionalSecretWithRotation() throws IOException { + SecretName name = TEST_REGIONAL_SECRET_WITH_ROTATION_TO_CREATE_NAME; + Secret secret = CreateRegionalSecretWithRotation.createRegionalSecretWithRotation( + name.getProject(), name.getLocation(), name.getSecret(), 2592000, PUBSUB_TOPIC_NAME); + + assertThat(stdOut.toString()).contains("Created secret"); + assertThat(stdOut.toString()).contains("with rotation"); + assertThat(secret.hasRotation()).isTrue(); + assertThat(secret.getTopicsCount()).isGreaterThan(0); + } + + @Test + public void testUpdateRegionalSecretRotation() throws IOException { + SecretName name = SecretName.parse(TEST_REGIONAL_SECRET_WITH_ROTATION.getName()); + Secret secret = UpdateRegionalSecretRotation.updateRegionalSecretRotation( + name.getProject(), name.getLocation(), name.getSecret(), 3600000, PUBSUB_TOPIC_NAME); + + assertThat(stdOut.toString()).contains("Updated secret"); + assertThat(stdOut.toString()).contains("with new rotation policy"); + assertThat(secret.hasRotation()).isTrue(); + assertThat(secret.getTopicsCount()).isGreaterThan(0); + } + + @Test + public void testDeleteRegionalSecretRotation() throws IOException { + SecretName name = SecretName.parse(TEST_REGIONAL_SECRET_WITH_ROTATION.getName()); + Secret secret = DeleteRegionalSecretRotation.deleteRegionalSecretRotation( + name.getProject(), name.getLocation(), name.getSecret()); + + assertThat(stdOut.toString()).contains("Deleted rotation from secret"); + assertThat(secret.hasRotation()).isFalse(); + } + + @Test + public void testCreateRegionalSecretWithTopic() throws IOException { + SecretName name = TEST_REGIONAL_SECRET_WITH_TOPIC_TO_CREATE_NAME; + Secret secret = CreateRegionalSecretWithTopic.createRegionalSecretWithTopic( + name.getProject(), name.getLocation(), name.getSecret(), PUBSUB_TOPIC_NAME); + + assertThat(stdOut.toString()).contains("Created secret"); + assertThat(stdOut.toString()).contains("with topic"); + assertThat(secret.getTopicsCount()).isGreaterThan(0); + } }