diff --git a/parametermanager/api/ParameterManager.Samples.Tests/CreateParameterWithKmsKeyTests.cs b/parametermanager/api/ParameterManager.Samples.Tests/CreateParameterWithKmsKeyTests.cs new file mode 100644 index 00000000000..99df82005eb --- /dev/null +++ b/parametermanager/api/ParameterManager.Samples.Tests/CreateParameterWithKmsKeyTests.cs @@ -0,0 +1,43 @@ +/* + * 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 + * + * https://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. + */ + +using Google.Cloud.Kms.V1; +using Google.Cloud.ParameterManager.V1; + +[Collection(nameof(ParameterManagerFixture))] +public class CreateParameterWithKmsKeyTests +{ + private readonly ParameterManagerFixture _fixture; + private readonly CreateParameterWithKmsKeySample _sample; + + public CreateParameterWithKmsKeyTests(ParameterManagerFixture fixture) + { + _fixture = fixture; + _sample = new CreateParameterWithKmsKeySample(); + } + + [Fact] + public void CreateParameterWithKmsKey() + { + ParameterName parameterName = _fixture.ParameterName; + Parameter result = _sample.CreateParameterWithKmsKey( + projectId: parameterName.ProjectId, parameterId: parameterName.ParameterId, kmsKey: _fixture.cryptoKey.Name); + + Assert.NotNull(result); + Assert.Equal(result.ParameterName.ParameterId, parameterName.ParameterId); + Assert.Equal(result.KmsKey, _fixture.cryptoKey.Name); + } +} diff --git a/parametermanager/api/ParameterManager.Samples.Tests/ParameterManager.Samples.Tests.csproj b/parametermanager/api/ParameterManager.Samples.Tests/ParameterManager.Samples.Tests.csproj new file mode 100644 index 00000000000..1a5ed58a25d --- /dev/null +++ b/parametermanager/api/ParameterManager.Samples.Tests/ParameterManager.Samples.Tests.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + enable + enable + false + + + + + + + + + + + + + + + + + + + diff --git a/parametermanager/api/ParameterManager.Samples.Tests/ParameterManagerFixture.cs b/parametermanager/api/ParameterManager.Samples.Tests/ParameterManagerFixture.cs new file mode 100644 index 00000000000..364b84fe31b --- /dev/null +++ b/parametermanager/api/ParameterManager.Samples.Tests/ParameterManagerFixture.cs @@ -0,0 +1,175 @@ +// Copyright(c) 2025 Google Inc. +// +// 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. + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.Kms.V1; +using Google.Cloud.ParameterManager.V1; +using Google.Protobuf; +using System.Text; + +[CollectionDefinition(nameof(ParameterManagerFixture))] +public class ParameterManagerFixture : IDisposable, ICollectionFixture +{ + public string ProjectId { get; } + public const string LocationId = "global"; + + public ParameterName ParameterName { get; } + + public CryptoKeyVersionName CryptoKeyVersionName1 { get; } + public CryptoKeyVersionName CryptoKeyVersionName2 { get; } + + public string ParameterId { get; } + public string KeyId { get; } + public string KeyId1 { get; } + + public Parameter UpdateParamKmsKey { get; } + public Parameter RemoveParamKmsKey { get; } + public CryptoKey cryptoKey { get; } + public CryptoKey cryptoKey1 { get; } + + + public ParameterManagerFixture() + { + ProjectId = Environment.GetEnvironmentVariable("GOOGLE_PROJECT_ID"); + if (String.IsNullOrEmpty(ProjectId)) + { + throw new Exception("missing GOOGLE_PROJECT_ID"); + } + + ParameterName = new ParameterName(ProjectId, LocationId, RandomId()); + + KeyRing keyRing = CreateKeyRing(ProjectId, "csharp-test-key-ring"); + + KeyId = RandomId(); + KeyId1 = RandomId(); + + cryptoKey = CreateHsmKey(ProjectId, KeyId, "csharp-test-key-ring"); + cryptoKey1 = CreateHsmKey(ProjectId, KeyId1, "csharp-test-key-ring"); + + ParameterId = RandomId(); + UpdateParamKmsKey = CreateParameterWithKmsKey(ParameterId, ParameterFormat.Unformatted, cryptoKey.Name); + + ParameterId = RandomId(); + RemoveParamKmsKey = CreateParameterWithKmsKey(ParameterId, ParameterFormat.Unformatted, cryptoKey.Name); + + CryptoKeyVersionName1 = new CryptoKeyVersionName(ProjectId, LocationId, "csharp-test-key-ring", KeyId, "1"); + CryptoKeyVersionName2 = new CryptoKeyVersionName(ProjectId, LocationId, "csharp-test-key-ring", KeyId1, "1"); + } + + public void Dispose() + { + DeleteParameter(ParameterName); + DeleteParameter(UpdateParamKmsKey.ParameterName); + DeleteParameter(RemoveParamKmsKey.ParameterName); + DeleteKeyVersion(CryptoKeyVersionName1); + DeleteKeyVersion(CryptoKeyVersionName2); + } + + public String RandomId() + { + return $"csharp-{System.Guid.NewGuid()}"; + } + + public Parameter CreateParameterWithKmsKey(string parameterId, ParameterFormat format, string kmsKey) + { + ParameterManagerClient client = ParameterManagerClient.Create(); + LocationName projectName = new LocationName(ProjectId, LocationId); + + Parameter parameter = new Parameter + { + Format = format, + KmsKey = kmsKey + }; + + return client.CreateParameter(projectName, parameter, parameterId); + } + + private void DeleteParameter(ParameterName name) + { + ParameterManagerClient client = ParameterManagerClient.Create(); + try + { + client.DeleteParameter(name); + } + catch (Grpc.Core.RpcException e) when (e.StatusCode == Grpc.Core.StatusCode.NotFound) + { + // Ignore error - Parameter was already deleted + } + } + + public KeyRing CreateKeyRing(string projectId, string keyRingId) + { + KeyManagementServiceClient client = KeyManagementServiceClient.Create(); + string name = $"projects/{projectId}/locations/global/keyRings/{keyRingId}"; + LocationName parent = new LocationName(projectId, "global"); + try + { + KeyRing resp = client.GetKeyRing(name); + return resp; + } + catch (Grpc.Core.RpcException e) when (e.StatusCode == Grpc.Core.StatusCode.NotFound) + { + return client.CreateKeyRing(new CreateKeyRingRequest + { + ParentAsLocationName = parent, + KeyRingId = keyRingId, + }); + } + } + + public CryptoKey CreateHsmKey(string projectId, string keyId, string keyRingId) + { + KeyManagementServiceClient client = KeyManagementServiceClient.Create(); + KeyRingName parent = new KeyRingName(projectId, "global", keyRingId); + + CreateCryptoKeyRequest request = new CreateCryptoKeyRequest + { + ParentAsKeyRingName = parent, + CryptoKeyId = keyId, + CryptoKey = new CryptoKey + { + Purpose = CryptoKey.Types.CryptoKeyPurpose.EncryptDecrypt, + VersionTemplate = new CryptoKeyVersionTemplate + { + Algorithm = CryptoKeyVersion.Types.CryptoKeyVersionAlgorithm.GoogleSymmetricEncryption, + ProtectionLevel = ProtectionLevel.Hsm, + }, + }, + }; + + try + { + string name = $"projects/{projectId}/locations/global/keyRings/{keyRingId}/cryptoKeys/{keyId}"; + CryptoKey resp = client.GetCryptoKey(name); + return resp; + } + catch (Grpc.Core.RpcException e) when (e.StatusCode == Grpc.Core.StatusCode.NotFound) + { + return client.CreateCryptoKey(request); + } + } + + public void DeleteKeyVersion(CryptoKeyVersionName name) + { + KeyManagementServiceClient client = KeyManagementServiceClient.Create(); + try + { + client.DestroyCryptoKeyVersion(name); + } + catch (Grpc.Core.RpcException e) when (e.StatusCode == Grpc.Core.StatusCode.NotFound) + { + // Ignore error - Parameter was already deleted + } + } +} diff --git a/parametermanager/api/ParameterManager.Samples.Tests/RemoveParameterKmsKeyTests.cs b/parametermanager/api/ParameterManager.Samples.Tests/RemoveParameterKmsKeyTests.cs new file mode 100644 index 00000000000..4141e624dce --- /dev/null +++ b/parametermanager/api/ParameterManager.Samples.Tests/RemoveParameterKmsKeyTests.cs @@ -0,0 +1,42 @@ +/* + * 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 + * + * https://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. + */ + +using Google.Cloud.Kms.V1; +using Google.Cloud.ParameterManager.V1; + +[Collection(nameof(ParameterManagerFixture))] +public class RemoveParameterKmsKeyTests +{ + private readonly ParameterManagerFixture _fixture; + private readonly RemoveParameterKmsKeySample _sample; + + public RemoveParameterKmsKeyTests(ParameterManagerFixture fixture) + { + _fixture = fixture; + _sample = new RemoveParameterKmsKeySample(); + } + + [Fact] + public void RemoveParameterKmsKey() + { + ParameterName parameterName = _fixture.ParameterName; + Parameter result = _sample.RemoveParameterKmsKey( + projectId: parameterName.ProjectId, parameterId: parameterName.ParameterId); + + Assert.NotNull(result); + Assert.Equal(result.ParameterName.ParameterId, parameterName.ParameterId); + } +} diff --git a/parametermanager/api/ParameterManager.Samples.Tests/UpdateParameterKmsKeyTests.cs b/parametermanager/api/ParameterManager.Samples.Tests/UpdateParameterKmsKeyTests.cs new file mode 100644 index 00000000000..6555f94a159 --- /dev/null +++ b/parametermanager/api/ParameterManager.Samples.Tests/UpdateParameterKmsKeyTests.cs @@ -0,0 +1,43 @@ +/* + * 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 + * + * https://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. + */ + +using Google.Cloud.Kms.V1; +using Google.Cloud.ParameterManager.V1; + +[Collection(nameof(ParameterManagerFixture))] +public class UpdateParameterKmsKeyTests +{ + private readonly ParameterManagerFixture _fixture; + private readonly UpdateParameterKmsKeySample _sample; + + public UpdateParameterKmsKeyTests(ParameterManagerFixture fixture) + { + _fixture = fixture; + _sample = new UpdateParameterKmsKeySample(); + } + + [Fact] + public void UpdateParameterKmsKey() + { + ParameterName parameterName = _fixture.ParameterName; + Parameter result = _sample.UpdateParameterKmsKey( + projectId: parameterName.ProjectId, parameterId: parameterName.ParameterId, kmsKey: _fixture.cryptoKey1.Name); + + Assert.NotNull(result); + Assert.Equal(result.ParameterName.ParameterId, parameterName.ParameterId); + Assert.Equal(result.KmsKey, _fixture.cryptoKey1.Name); + } +} diff --git a/parametermanager/api/ParameterManager.Samples/CreateParameterWithKmsKey.cs b/parametermanager/api/ParameterManager.Samples/CreateParameterWithKmsKey.cs new file mode 100644 index 00000000000..35f909eca71 --- /dev/null +++ b/parametermanager/api/ParameterManager.Samples/CreateParameterWithKmsKey.cs @@ -0,0 +1,59 @@ +/* + * 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 + * + * https://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. + */ + +// [START parametermanager_create_param_with_kms_key] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.ParameterManager.V1; + +public class CreateParameterWithKmsKeySample +{ + /// + /// This function creates a parameter with kms_key using the Parameter Manager SDK for GCP. + /// + /// The ID of the project where the parameter is to be created. + /// The ID to assign to the new parameter. This ID must be unique within the project. + /// The ID of the KMS key to be used for encryption. + /// (e.g. "projects/my-project/locations/global/keyRings/my-key-ring/cryptoKeys/my-encryption-key") + /// The created Parameter object. + public Parameter CreateParameterWithKmsKey( + string projectId, + string parameterId, + string kmsKey) + { + // Create the client. + ParameterManagerClient client = ParameterManagerClient.Create(); + + // Build the parent resource name. + LocationName parent = new LocationName(projectId, "global"); + + // Build the parameter. + Parameter parameter = new Parameter + { + KmsKey = kmsKey + }; + + // Call the API to create the parameter. + Parameter createdParameter = client.CreateParameter(parent, parameter, parameterId); + + // Print the created parameter name with kms_key. + Console.WriteLine($"Created parameter {createdParameter.Name} with kms_key {createdParameter.KmsKey}"); + + // Return the created parameter. + return createdParameter; + } +} +// [END parametermanager_create_param_with_kms_key] diff --git a/parametermanager/api/ParameterManager.Samples/ParameterManager.Samples.csproj b/parametermanager/api/ParameterManager.Samples/ParameterManager.Samples.csproj new file mode 100644 index 00000000000..a3193a526b6 --- /dev/null +++ b/parametermanager/api/ParameterManager.Samples/ParameterManager.Samples.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + false + + + + + + diff --git a/parametermanager/api/ParameterManager.Samples/RemoveParameterKmsKey.cs b/parametermanager/api/ParameterManager.Samples/RemoveParameterKmsKey.cs new file mode 100644 index 00000000000..8bbfee621a5 --- /dev/null +++ b/parametermanager/api/ParameterManager.Samples/RemoveParameterKmsKey.cs @@ -0,0 +1,64 @@ +/* + * 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 + * + * https://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. + */ + +// [START parametermanager_remove_param_kms_key] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.ParameterManager.V1; +using Google.Protobuf.WellKnownTypes; + +public class RemoveParameterKmsKeySample +{ + /// + /// This function Removes a kms_key for parameter using the Parameter Manager SDK for GCP. + /// + /// The ID of the project where the parameter is to be created. + /// The ID to assign to the new parameter. This ID must be unique within the project. + /// The Parameter object. + public Parameter RemoveParameterKmsKey( + string projectId, + string parameterId) + { + // Create the client. + ParameterManagerClient client = ParameterManagerClient.Create(); + + // Build the parent resource name. + ParameterName name = new ParameterName(projectId, "global", parameterId); + + // Build the parameter. + UpdateParameterRequest request = new UpdateParameterRequest + { + Parameter = new Parameter + { + Name = name.ToString(), + }, + UpdateMask = new FieldMask + { + Paths = { "kms_key" } + } + }; + + // Call the API to create the parameter. + Parameter updatedParameter = client.UpdateParameter(request); + + // Print the updated parameter name with kms_key. + Console.WriteLine($"Removed kms_key for parameter {updatedParameter.Name}"); + + // Return the updated parameter. + return updatedParameter; + } +} +// [END parametermanager_remove_param_kms_key] diff --git a/parametermanager/api/ParameterManager.Samples/UpdateParameterKmsKey.cs b/parametermanager/api/ParameterManager.Samples/UpdateParameterKmsKey.cs new file mode 100644 index 00000000000..01f918117db --- /dev/null +++ b/parametermanager/api/ParameterManager.Samples/UpdateParameterKmsKey.cs @@ -0,0 +1,68 @@ +/* + * 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 + * + * https://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. + */ + +// [START parametermanager_update_param_kms_key] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.ParameterManager.V1; +using Google.Protobuf.WellKnownTypes; + +public class UpdateParameterKmsKeySample +{ + /// + /// This function updates a parameter with kms_key using the Parameter Manager SDK for GCP. + /// + /// The ID of the project where the parameter is to be updated. + /// The ID to assign to the new parameter. This ID must be unique within the project. + /// The ID of the KMS key to be used for encryption. + /// (e.g. "projects/my-project/locations/global/keyRings/my-key-ring/cryptoKeys/my-encryption-key") + /// The updated Parameter object. + public Parameter UpdateParameterKmsKey( + string projectId, + string parameterId, + string kmsKey) + { + // Create the client. + ParameterManagerClient client = ParameterManagerClient.Create(); + + // Build the parent resource name. + ParameterName name = new ParameterName(projectId, "global", parameterId); + + // Build the parameter. + UpdateParameterRequest request = new UpdateParameterRequest + { + Parameter = new Parameter + { + Name = name.ToString(), + KmsKey = kmsKey + }, + UpdateMask = new FieldMask + { + Paths = { "kms_key" } + } + }; + + // Call the API to create the parameter. + Parameter updatedParameter = client.UpdateParameter(request); + + // Print the updated parameter name with kms_key. + Console.WriteLine($"Updated parameter {updatedParameter.Name} with kms_key {updatedParameter.KmsKey}"); + + // Return the updated parameter. + return updatedParameter; + } +} +// [END parametermanager_update_param_kms_key] diff --git a/parametermanager/api/ParameterManager.sln b/parametermanager/api/ParameterManager.sln new file mode 100644 index 00000000000..2508412fd3d --- /dev/null +++ b/parametermanager/api/ParameterManager.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParameterManager.Samples", "ParameterManager.Samples\ParameterManager.Samples.csproj", "{3E86B4EA-CA57-4E41-8D9A-FAB8F97F4779}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParameterManager.Samples.Tests", "ParameterManager.Samples.Tests\ParameterManager.Samples.Tests.csproj", "{0684F22B-8869-47CF-9480-31FE68756B04}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3E86B4EA-CA57-4E41-8D9A-FAB8F97F4779}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E86B4EA-CA57-4E41-8D9A-FAB8F97F4779}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E86B4EA-CA57-4E41-8D9A-FAB8F97F4779}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E86B4EA-CA57-4E41-8D9A-FAB8F97F4779}.Release|Any CPU.Build.0 = Release|Any CPU + {0684F22B-8869-47CF-9480-31FE68756B04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0684F22B-8869-47CF-9480-31FE68756B04}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0684F22B-8869-47CF-9480-31FE68756B04}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0684F22B-8869-47CF-9480-31FE68756B04}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/parametermanager/api/runTests.ps1 b/parametermanager/api/runTests.ps1 new file mode 100755 index 00000000000..05d154e7749 --- /dev/null +++ b/parametermanager/api/runTests.ps1 @@ -0,0 +1,16 @@ +# 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 +# +# https://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. + +dotnet restore --force +dotnet test --no-restore --test-adapter-path:. --logger:junit 2>&1 | %{ "$_" }