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/regionalsamples/CreateRegionalParamWithKmsKey.java b/parametermanager/src/main/java/parametermanager/regionalsamples/CreateRegionalParamWithKmsKey.java new file mode 100644 index 00000000000..8eccd640d5a --- /dev/null +++ b/parametermanager/src/main/java/parametermanager/regionalsamples/CreateRegionalParamWithKmsKey.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.regionalsamples; + +// [START parametermanager_create_regional_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 com.google.cloud.parametermanager.v1.ParameterManagerSettings; +import java.io.IOException; + +/** + * Example class to create a new regional parameter with provided KMS + * key using the Parameter Manager SDK for GCP. + */ +public class CreateRegionalParamWithKmsKey { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String locationId = "your-location-id"; + String parameterId = "your-parameter-id"; + String kmsKeyName = "your-kms-key"; + + // Call the method to create a regional parameter with the specified kms key. + createRegionalParameterWithKmsKey(projectId, locationId, parameterId, kmsKeyName); + } + + // This is an example snippet for creating a new parameter with a specific format. + public static Parameter createRegionalParameterWithKmsKey( + String projectId, String locationId, String parameterId, String kmsKeyName) + throws IOException { + + // Endpoint to call the regional parameter manager server + String apiEndpoint = String.format("parametermanager.%s.rep.googleapis.com:443", locationId); + ParameterManagerSettings parameterManagerSettings = + ParameterManagerSettings.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 (ParameterManagerClient client = ParameterManagerClient.create(parameterManagerSettings)) { + + // 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 regional parameter %s with kms key %s\n", + createdParameter.getName(), createdParameter.getKmsKey()); + + return createdParameter; + } + } +} +// [END parametermanager_create_regional_param_with_kms_key] diff --git a/parametermanager/src/main/java/parametermanager/regionalsamples/RemoveRegionalParamKmsKey.java b/parametermanager/src/main/java/parametermanager/regionalsamples/RemoveRegionalParamKmsKey.java new file mode 100644 index 00000000000..4614b5321c4 --- /dev/null +++ b/parametermanager/src/main/java/parametermanager/regionalsamples/RemoveRegionalParamKmsKey.java @@ -0,0 +1,80 @@ +/* + * 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.regionalsamples; + +// [START parametermanager_remove_regional_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 RemoveRegionalParamKmsKey { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String locationId = "your-location-id"; + String parameterId = "your-parameter-id"; + + // Call the method to remove kms key of a parameter. + removeRegionalParamKmsKey(projectId, locationId, parameterId); + } + + // This is an example snippet for updating the kms key of a parameter. + public static Parameter removeRegionalParamKmsKey( + String projectId, String locationId, String parameterId) throws IOException { + + // Endpoint to call the regional parameter manager server + String apiEndpoint = String.format("parametermanager.%s.rep.googleapis.com:443", locationId); + ParameterManagerSettings parameterManagerSettings = + ParameterManagerSettings.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 (ParameterManagerClient client = ParameterManagerClient.create(parameterManagerSettings)) { + + // 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 regional parameter %s\n", + updatedParameter.getName()); + + return updatedParameter; + } + } +} +// [END parametermanager_remove_regional_param_kms_key] diff --git a/parametermanager/src/main/java/parametermanager/regionalsamples/UpdateRegionalParamKmsKey.java b/parametermanager/src/main/java/parametermanager/regionalsamples/UpdateRegionalParamKmsKey.java new file mode 100644 index 00000000000..eb55f344073 --- /dev/null +++ b/parametermanager/src/main/java/parametermanager/regionalsamples/UpdateRegionalParamKmsKey.java @@ -0,0 +1,82 @@ +/* + * 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.regionalsamples; + +// [START parametermanager_update_regional_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 regional + * parameter using the Parameter Manager SDK for GCP. + */ +public class UpdateRegionalParamKmsKey { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + String projectId = "your-project-id"; + String locationId = "your-location-id"; + String parameterId = "your-parameter-id"; + String kmsKeyName = "your-kms-key"; + + // Call the method to update kms key of a parameter. + updateRegionalParamKmsKey(projectId, locationId, parameterId, kmsKeyName); + } + + // This is an example snippet for updating the kms key of a parameter. + public static Parameter updateRegionalParamKmsKey( + String projectId, String locationId, String parameterId, String kmsKeyName) + throws IOException { + + // Endpoint to call the regional parameter manager server + String apiEndpoint = String.format("parametermanager.%s.rep.googleapis.com:443", locationId); + ParameterManagerSettings parameterManagerSettings = + ParameterManagerSettings.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 (ParameterManagerClient client = ParameterManagerClient.create(parameterManagerSettings)) { + + // 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 regional parameter %s with kms key %s\n", + updatedParameter.getName(), updatedParameter.getKmsKey()); + + return updatedParameter; + } + } +} +// [END parametermanager_update_regional_param_kms_key] diff --git a/parametermanager/src/test/java/parametermanager/regionalsamples/SnippetsIT.java b/parametermanager/src/test/java/parametermanager/regionalsamples/SnippetsIT.java index 696339ab394..4a452e3282d 100644 --- a/parametermanager/src/test/java/parametermanager/regionalsamples/SnippetsIT.java +++ b/parametermanager/src/test/java/parametermanager/regionalsamples/SnippetsIT.java @@ -17,7 +17,18 @@ package parametermanager.regionalsamples; 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; @@ -79,6 +92,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 @@ -178,6 +197,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, LOCATION_ID, randomId()); + KEY_RING_ID = "test-regional-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, LOCATION_ID, randomId()); + KEY_RING_ID = "test-regional-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, LOCATION_ID, 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, LOCATION_ID, randomId()); + KEY_RING_ID = "test-regional-parameter-manager-snippets"; + HSM_KEY_ID = randomId(); + createKeyRing(KEY_RING_ID); + createHsmKey(HSM_KEY_ID); + kmsKeyId = CryptoKeyName.of(PROJECT_ID, LOCATION_ID, KEY_RING_ID, HSM_KEY_ID).toString(); + createParameterWithKms(TEST_PARAMETER_NAME_DELETE_WITH_KMS.getParameter(), kmsKeyId); } @AfterClass @@ -208,6 +254,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() { @@ -215,6 +288,14 @@ private static String randomId() { return "java-" + random.nextLong(); } + private static KeyRingName getKeyRingName() { + return KeyRingName.of(PROJECT_ID, LOCATION_ID, KEY_RING_ID); + } + + private static com.google.cloud.kms.v1.LocationName getLocationName() { + return com.google.cloud.kms.v1.LocationName.of(PROJECT_ID, LOCATION_ID); + } + private static Parameter createParameter(String parameterId, ParameterFormat format) throws IOException { // Endpoint to call the regional parameter manager server @@ -230,6 +311,52 @@ private static Parameter createParameter(String parameterId, ParameterFormat for } } + private static Parameter createParameterWithKms(String parameterId, String kmsKeyId) + throws IOException { + // Endpoint to call the regional parameter manager server + String apiEndpoint = String.format("parametermanager.%s.rep.googleapis.com:443", LOCATION_ID); + ParameterManagerSettings parameterManagerSettings = + ParameterManagerSettings.newBuilder().setEndpoint(apiEndpoint).build(); + + LocationName parent = LocationName.of(PROJECT_ID, LOCATION_ID); + Parameter parameter = Parameter.newBuilder().setKmsKey(kmsKeyId).build(); + + try (ParameterManagerClient client = ParameterManagerClient.create(parameterManagerSettings)) { + 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, LOCATION_ID, 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 { // Endpoint to call the regional parameter manager server @@ -517,6 +644,59 @@ public void testEnableRegionalParameterVersion() throws IOException { assertThat(stdOut.toString()).contains("Enabled regional parameter version"); } + @Test + public void testCreateRegionalParamWithKmsKey() throws IOException { + ParameterName parameterName = TEST_PARAMETER_NAME_WITH_KMS; + String cryptoKey = CryptoKeyName.of(PROJECT_ID, LOCATION_ID, KEY_RING_ID, HSM_KEY_ID) + .toString(); + CreateRegionalParamWithKmsKey + .createRegionalParameterWithKmsKey( + parameterName.getProject(), + LOCATION_ID, + parameterName.getParameter(), + cryptoKey); + + String expected = String.format( + "Created regional parameter %s with kms key %s\n", + parameterName, cryptoKey); + assertThat(stdOut.toString()).contains(expected); + } + + @Test + public void testUpdateRegionalParamKmsKey() throws IOException { + ParameterName parameterName = TEST_PARAMETER_NAME_UPDATE_WITH_KMS; + String cryptoKey = CryptoKeyName.of(PROJECT_ID, LOCATION_ID, KEY_RING_ID, NEW_HSM_KEY_ID) + .toString(); + Parameter updatedParameter = UpdateRegionalParamKmsKey + .updateRegionalParamKmsKey( + parameterName.getProject(), + LOCATION_ID, + parameterName.getParameter(), + cryptoKey); + + String expected = String.format( + "Updated regional 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 testRemoveRegionalParamKmsKey() throws IOException { + ParameterName parameterName = TEST_PARAMETER_NAME_DELETE_WITH_KMS; + Parameter updatedParameter = RemoveRegionalParamKmsKey + .removeRegionalParamKmsKey( + parameterName.getProject(), LOCATION_ID, parameterName.getParameter()); + + String expected = String.format( + "Removed kms key for regional parameter %s\n", + parameterName); + assertThat(stdOut.toString()).contains(expected); + assertEquals("", updatedParameter.getKmsKey()); + } + + @Test public void testDeleteRegionalParameterVersion() throws IOException { ParameterVersionName parameterVersionName = TEST_PARAMETER_VERSION_NAME_TO_DELETE;