From ac72f71a311e9efe766fda49984e382be0bc6d22 Mon Sep 17 00:00:00 2001 From: durgesh-ninave-crest Date: Fri, 16 May 2025 18:13:11 +0530 Subject: [PATCH 1/2] Added samples for kms_key field in global parameter --- parametermanager/pom.xml | 7 +- .../CreateParamWithKmsKey.java | 66 +++++++ .../parametermanager/RemoveParamKmsKey.java | 74 ++++++++ .../parametermanager/UpdateParamKmsKey.java | 75 ++++++++ .../java/parametermanager/SnippetsIT.java | 168 +++++++++++++++++- 5 files changed, 388 insertions(+), 2 deletions(-) create mode 100644 parametermanager/src/main/java/parametermanager/CreateParamWithKmsKey.java create mode 100644 parametermanager/src/main/java/parametermanager/RemoveParamKmsKey.java create mode 100644 parametermanager/src/main/java/parametermanager/UpdateParamKmsKey.java diff --git a/parametermanager/pom.xml b/parametermanager/pom.xml index 17deb982a30..33cd5ffdc52 100644 --- a/parametermanager/pom.xml +++ b/parametermanager/pom.xml @@ -43,7 +43,7 @@ com.google.cloud libraries-bom - 26.54.0 + 26.60.0 pom import @@ -91,6 +91,11 @@ google-iam-policy test + + com.google.cloud + google-cloud-kms + test + diff --git a/parametermanager/src/main/java/parametermanager/CreateParamWithKmsKey.java b/parametermanager/src/main/java/parametermanager/CreateParamWithKmsKey.java new file mode 100644 index 00000000000..c15bf7df2d9 --- /dev/null +++ b/parametermanager/src/main/java/parametermanager/CreateParamWithKmsKey.java @@ -0,0 +1,66 @@ +/* + * Copyright 2025 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 parametermanager; + +// [START parametermanager_create_param_with_kms_key] + +import com.google.cloud.parametermanager.v1.LocationName; +import com.google.cloud.parametermanager.v1.Parameter; +import com.google.cloud.parametermanager.v1.ParameterManagerClient; +import java.io.IOException; + +/** + * Example class to create a new parameter with provided KMS key + * using the Parameter Manager SDK for GCP. + */ +public class CreateParamWithKmsKey { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String parameterId = "your-parameter-id"; + String kmsKeyName = "your-kms-key"; + + // Call the method to create a parameter with the specified kms key. + createParameterWithKmsKey(projectId, parameterId, kmsKeyName); + } + + // This is an example snippet for creating a new parameter with a specific format. + public static Parameter createParameterWithKmsKey( + String projectId, String parameterId, String kmsKeyName) throws IOException { + // Initialize the client that will be used to send requests. + try (ParameterManagerClient client = ParameterManagerClient.create()) { + String locationId = "global"; + + // Build the parent name from the project. + LocationName location = LocationName.of(projectId, locationId); + + // Build the parameter to create with the provided format. + Parameter parameter = Parameter.newBuilder().setKmsKey(kmsKeyName).build(); + + // Create the parameter. + Parameter createdParameter = + client.createParameter(location.toString(), parameter, parameterId); + System.out.printf( + "Created parameter %s with kms key %s\n", + createdParameter.getName(), createdParameter.getKmsKey()); + + return createdParameter; + } + } +} +// [END parametermanager_create_param_with_kms_key] diff --git a/parametermanager/src/main/java/parametermanager/RemoveParamKmsKey.java b/parametermanager/src/main/java/parametermanager/RemoveParamKmsKey.java new file mode 100644 index 00000000000..f6312503fc1 --- /dev/null +++ b/parametermanager/src/main/java/parametermanager/RemoveParamKmsKey.java @@ -0,0 +1,74 @@ +/* + * Copyright 2025 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 parametermanager; + +// [START parametermanager_remove_param_kms_key] + +import com.google.cloud.parametermanager.v1.Parameter; +import com.google.cloud.parametermanager.v1.ParameterManagerClient; +import com.google.cloud.parametermanager.v1.ParameterManagerSettings; +import com.google.cloud.parametermanager.v1.ParameterName; +import com.google.protobuf.FieldMask; +import com.google.protobuf.util.FieldMaskUtil; +import java.io.IOException; + +/** + * This class demonstrates how to change the kms key of a parameter + * using the Parameter Manager SDK for GCP. + */ +public class RemoveParamKmsKey { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String parameterId = "your-parameter-id"; + + // Call the method to remove kms key of a parameter. + removeParamKmsKey(projectId, parameterId); + } + + // This is an example snippet for updating the kms key of a parameter. + public static Parameter removeParamKmsKey( + String projectId, String parameterId) throws IOException { + // 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 (ParameterManagerClient client = ParameterManagerClient.create()) { + String locationId = "global"; + + // Build the parameter name. + ParameterName name = ParameterName.of(projectId, locationId, parameterId); + + // Remove kms key of a parameter . + Parameter parameter = Parameter.newBuilder() + .setName(name.toString()) + .clearKmsKey() + .build(); + + // Build the field mask for the kms_key field. + FieldMask fieldMask = FieldMaskUtil.fromString("kms_key"); + + // Update the parameter kms key. + Parameter updatedParameter = client.updateParameter(parameter, fieldMask); + System.out.printf( + "Removed kms key for parameter %s\n", + updatedParameter.getName()); + + return updatedParameter; + } + } +} +// [END parametermanager_remove_param_kms_key] diff --git a/parametermanager/src/main/java/parametermanager/UpdateParamKmsKey.java b/parametermanager/src/main/java/parametermanager/UpdateParamKmsKey.java new file mode 100644 index 00000000000..1a906fb768f --- /dev/null +++ b/parametermanager/src/main/java/parametermanager/UpdateParamKmsKey.java @@ -0,0 +1,75 @@ +/* + * Copyright 2025 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 parametermanager; + +// [START parametermanager_update_param_kms_key] + +import com.google.cloud.parametermanager.v1.Parameter; +import com.google.cloud.parametermanager.v1.ParameterManagerClient; +import com.google.cloud.parametermanager.v1.ParameterManagerSettings; +import com.google.cloud.parametermanager.v1.ParameterName; +import com.google.protobuf.FieldMask; +import com.google.protobuf.util.FieldMaskUtil; +import java.io.IOException; + +/** + * This class demonstrates how to change the kms key of a parameter + * using theParameter Manager SDK for GCP. + */ +public class UpdateParamKmsKey { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String parameterId = "your-parameter-id"; + String kmsKeyName = "your-kms-key"; + + // Call the method to update kms key of a parameter. + updateParamKmsKey(projectId, parameterId, kmsKeyName); + } + + // This is an example snippet for updating the kms key of a parameter. + public static Parameter updateParamKmsKey( + String projectId, String parameterId, String kmsKeyName) throws IOException { + // 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 (ParameterManagerClient client = ParameterManagerClient.create()) { + String locationId = "global"; + + // Build the parameter name. + ParameterName name = ParameterName.of(projectId, locationId, parameterId); + + // Set the parameter kms key to update. + Parameter parameter = Parameter.newBuilder() + .setName(name.toString()) + .setKmsKey(kmsKeyName) + .build(); + + // Build the field mask for the kms_key field. + FieldMask fieldMask = FieldMaskUtil.fromString("kms_key"); + + // Update the parameter kms key. + Parameter updatedParameter = client.updateParameter(parameter, fieldMask); + System.out.printf( + "Updated parameter %s with kms key %s\n", + updatedParameter.getName(), updatedParameter.getKmsKey()); + + return updatedParameter; + } + } +} +// [END parametermanager_update_param_kms_key] diff --git a/parametermanager/src/test/java/parametermanager/SnippetsIT.java b/parametermanager/src/test/java/parametermanager/SnippetsIT.java index bbeac0d74a1..1dddf7fb802 100644 --- a/parametermanager/src/test/java/parametermanager/SnippetsIT.java +++ b/parametermanager/src/test/java/parametermanager/SnippetsIT.java @@ -17,7 +17,18 @@ package parametermanager; import static com.google.common.truth.Truth.assertThat; - +import static org.junit.Assert.assertEquals; + +import com.google.api.gax.rpc.AlreadyExistsException; +import com.google.cloud.kms.v1.CryptoKey; +import com.google.cloud.kms.v1.CryptoKeyName; +import com.google.cloud.kms.v1.CryptoKeyVersion; +import com.google.cloud.kms.v1.CryptoKeyVersionTemplate; +import com.google.cloud.kms.v1.KeyManagementServiceClient; +import com.google.cloud.kms.v1.KeyRing; +import com.google.cloud.kms.v1.KeyRingName; +import com.google.cloud.kms.v1.ListCryptoKeyVersionsRequest; +import com.google.cloud.kms.v1.ProtectionLevel; import com.google.cloud.parametermanager.v1.LocationName; import com.google.cloud.parametermanager.v1.Parameter; import com.google.cloud.parametermanager.v1.ParameterFormat; @@ -39,6 +50,8 @@ import com.google.iam.v1.Policy; import com.google.iam.v1.SetIamPolicyRequest; import com.google.protobuf.ByteString; +import com.google.protobuf.FieldMask; +import com.google.protobuf.util.FieldMaskUtil; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; @@ -76,6 +89,12 @@ public class SnippetsIT { private static ParameterName TEST_PARAMETER_NAME_TO_RENDER; private static ParameterVersionName TEST_PARAMETER_VERSION_NAME_TO_RENDER; private static SecretName SECRET_NAME; + private static ParameterName TEST_PARAMETER_NAME_WITH_KMS; + private static String KEY_RING_ID; + private static String HSM_KEY_ID; + private static ParameterName TEST_PARAMETER_NAME_UPDATE_WITH_KMS; + private static String NEW_HSM_KEY_ID; + private static ParameterName TEST_PARAMETER_NAME_DELETE_WITH_KMS; private ByteArrayOutputStream stdOut; @BeforeClass @@ -164,6 +183,33 @@ public static void beforeAll() throws IOException { TEST_PARAMETER_VERSION_NAME_TO_RENDER.getParameter(), TEST_PARAMETER_VERSION_NAME_TO_RENDER.getParameterVersion(), payload); + + // test create parameter with kms key + TEST_PARAMETER_NAME_WITH_KMS = ParameterName.of(PROJECT_ID, "global", randomId()); + KEY_RING_ID = "test-parameter-manager-snippets"; + HSM_KEY_ID = randomId(); + createKeyRing(KEY_RING_ID); + createHsmKey(HSM_KEY_ID); + + // test update kms key of parameter + TEST_PARAMETER_NAME_UPDATE_WITH_KMS = ParameterName.of(PROJECT_ID, "global", randomId()); + KEY_RING_ID = "test-parameter-manager-snippets"; + HSM_KEY_ID = randomId(); + NEW_HSM_KEY_ID = randomId(); + createKeyRing(KEY_RING_ID); + createHsmKey(HSM_KEY_ID); + createHsmKey(NEW_HSM_KEY_ID); + String kmsKeyId = CryptoKeyName.of(PROJECT_ID, "global", KEY_RING_ID, HSM_KEY_ID).toString(); + createParameterWithKms(TEST_PARAMETER_NAME_UPDATE_WITH_KMS.getParameter(), kmsKeyId); + + // test delete kms key of parameter + TEST_PARAMETER_NAME_DELETE_WITH_KMS = ParameterName.of(PROJECT_ID, "global", randomId()); + KEY_RING_ID = "test-parameter-manager-snippets"; + HSM_KEY_ID = randomId(); + createKeyRing(KEY_RING_ID); + createHsmKey(HSM_KEY_ID); + kmsKeyId = CryptoKeyName.of(PROJECT_ID, "global", KEY_RING_ID, HSM_KEY_ID).toString(); + createParameterWithKms(TEST_PARAMETER_NAME_DELETE_WITH_KMS.getParameter(), kmsKeyId); } @AfterClass @@ -191,6 +237,33 @@ public static void afterAll() throws IOException { deleteParameterVersion(TEST_PARAMETER_VERSION_NAME_TO_GET.toString()); deleteParameterVersion(TEST_PARAMETER_VERSION_NAME_TO_GET_1.toString()); deleteParameter(TEST_PARAMETER_NAME_TO_GET.toString()); + + deleteParameter(TEST_PARAMETER_NAME_WITH_KMS.toString()); + + deleteParameter(TEST_PARAMETER_NAME_UPDATE_WITH_KMS.toString()); + + deleteParameter(TEST_PARAMETER_NAME_DELETE_WITH_KMS.toString()); + + // Iterate over each key ring's key's crypto key versions and destroy. + try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) { + for (CryptoKey key : client.listCryptoKeys(getKeyRingName()).iterateAll()) { + if (key.hasRotationPeriod() || key.hasNextRotationTime()) { + CryptoKey keyWithoutRotation = CryptoKey.newBuilder().setName(key.getName()).build(); + FieldMask fieldMask = FieldMaskUtil.fromString("rotation_period,next_rotation_time"); + client.updateCryptoKey(keyWithoutRotation, fieldMask); + } + + ListCryptoKeyVersionsRequest listVersionsRequest = + ListCryptoKeyVersionsRequest.newBuilder() + .setParent(key.getName()) + .setFilter("state != DESTROYED AND state != DESTROY_SCHEDULED") + .build(); + for (CryptoKeyVersion version : + client.listCryptoKeyVersions(listVersionsRequest).iterateAll()) { + client.destroyCryptoKeyVersion(version.getName()); + } + } + } } private static String randomId() { @@ -198,6 +271,14 @@ private static String randomId() { return "java-" + random.nextLong(); } + private static KeyRingName getKeyRingName() { + return KeyRingName.of(PROJECT_ID, "global", KEY_RING_ID); + } + + private static com.google.cloud.kms.v1.LocationName getLocationName() { + return com.google.cloud.kms.v1.LocationName.of(PROJECT_ID, "global"); + } + private static Parameter createParameter(String parameterId, ParameterFormat format) throws IOException { LocationName parent = LocationName.of(PROJECT_ID, "global"); @@ -208,6 +289,48 @@ private static Parameter createParameter(String parameterId, ParameterFormat for } } + private static Parameter createParameterWithKms(String parameterId, String kmsKeyId) + throws IOException { + LocationName parent = LocationName.of(PROJECT_ID, "global"); + Parameter parameter = Parameter.newBuilder().setKmsKey(kmsKeyId).build(); + + try (ParameterManagerClient client = ParameterManagerClient.create()) { + return client.createParameter(parent.toString(), parameter, parameterId); + } + } + + private static KeyRing createKeyRing(String keyRingId) throws IOException { + try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) { + KeyRing keyRing = KeyRing.newBuilder().build(); + KeyRing createdKeyRing = client.createKeyRing(getLocationName(), keyRingId, keyRing); + return createdKeyRing; + } catch (AlreadyExistsException e) { + try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) { + return client.getKeyRing(KeyRingName.of(PROJECT_ID, "global", keyRingId)); + } + } + } + + private static CryptoKey createHsmKey(String keyId) throws IOException { + try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) { + CryptoKey key = + CryptoKey.newBuilder() + .setPurpose(CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT) + .setVersionTemplate( + CryptoKeyVersionTemplate.newBuilder() + .setAlgorithm(CryptoKeyVersion + .CryptoKeyVersionAlgorithm + .GOOGLE_SYMMETRIC_ENCRYPTION) + .setProtectionLevel(ProtectionLevel.HSM) + .build()) + .putLabels("foo", "bar") + .putLabels("zip", "zap") + .build(); + CryptoKey createdKey = client.createCryptoKey(getKeyRingName(), keyId, key); + return createdKey; + } + } + private static void createParameterVersion(String parameterId, String versionId, String payload) throws IOException { ParameterName parameterName = ParameterName.of(PROJECT_ID, "global", parameterId); @@ -443,6 +566,49 @@ public void testCreateParamVersion() throws IOException { assertThat(stdOut.toString()).contains("Created parameter version"); } + @Test + public void testCreateParamWithKmsKey() throws IOException { + ParameterName parameterName = TEST_PARAMETER_NAME_WITH_KMS; + String cryptoKey = CryptoKeyName.of(PROJECT_ID, "global", KEY_RING_ID, HSM_KEY_ID).toString(); + CreateParamWithKmsKey.createParameterWithKmsKey( + parameterName.getProject(), parameterName.getParameter(), cryptoKey); + + String expected = String.format( + "Created parameter %s with kms key %s\n", + parameterName, cryptoKey); + assertThat(stdOut.toString()).contains(expected); + } + + @Test + public void testUpdateParamKmsKey() throws IOException { + ParameterName parameterName = TEST_PARAMETER_NAME_UPDATE_WITH_KMS; + String cryptoKey = CryptoKeyName + .of(PROJECT_ID, "global", KEY_RING_ID, NEW_HSM_KEY_ID) + .toString(); + Parameter updatedParameter = UpdateParamKmsKey + .updateParamKmsKey(parameterName.getProject(), parameterName.getParameter(), cryptoKey); + + String expected = String.format( + "Updated parameter %s with kms key %s\n", + parameterName, cryptoKey); + assertThat(stdOut.toString()).contains(expected); + assertThat(updatedParameter.getKmsKey()).contains(NEW_HSM_KEY_ID); + assertThat(updatedParameter.getKmsKey()).doesNotContain(HSM_KEY_ID); + } + + @Test + public void testRemoveParamKmsKey() throws IOException { + ParameterName parameterName = TEST_PARAMETER_NAME_DELETE_WITH_KMS; + Parameter updatedParameter = RemoveParamKmsKey + .removeParamKmsKey(parameterName.getProject(), parameterName.getParameter()); + + String expected = String.format( + "Removed kms key for parameter %s\n", + parameterName); + assertThat(stdOut.toString()).contains(expected); + assertEquals("", updatedParameter.getKmsKey()); + } + @Test public void testStructuredCreateParamVersion() throws IOException { ParameterVersionName parameterVersionName = TEST_PARAMETER_VERSION_NAME_WITH_FORMAT; From 3956f2e74b9b11f9b38f1509771cf6f3557f2a46 Mon Sep 17 00:00:00 2001 From: durgesh-ninave-crest Date: Tue, 17 Jun 2025 14:22:20 +0530 Subject: [PATCH 2/2] fix(parametermanager): update sleep time for render regional parameter version --- .../test/java/parametermanager/regionalsamples/SnippetsIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parametermanager/src/test/java/parametermanager/regionalsamples/SnippetsIT.java b/parametermanager/src/test/java/parametermanager/regionalsamples/SnippetsIT.java index 4a452e3282d..baf346f1dae 100644 --- a/parametermanager/src/test/java/parametermanager/regionalsamples/SnippetsIT.java +++ b/parametermanager/src/test/java/parametermanager/regionalsamples/SnippetsIT.java @@ -181,7 +181,7 @@ public static void beforeAll() throws IOException { createParameter(TEST_PARAMETER_NAME_TO_RENDER.getParameter(), ParameterFormat.JSON); iamGrantAccess(SECRET_NAME, testParameter.getPolicyMember().getIamPolicyUidPrincipal()); try { - Thread.sleep(60000); + Thread.sleep(120000); } catch (InterruptedException e) { throw new RuntimeException(e); }