diff --git a/secretmanager/api/SecretManager.Samples.Tests/BindTagToRegionalSecretTests.cs b/secretmanager/api/SecretManager.Samples.Tests/BindTagToRegionalSecretTests.cs new file mode 100644 index 00000000000..b1009d0bb6e --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/BindTagToRegionalSecretTests.cs @@ -0,0 +1,143 @@ +/* + * 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 + * + * 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.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.IO; +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class BindTagsToRegionalSecretTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly BindTagsToRegionalSecretSample _sample; + private readonly TagKeysClient _tagKeysClient; + private readonly TagValuesClient _tagValuesClient; + private readonly TagBindingsClient _tagBindingsClient; + private string _tagKeyName; + private string _tagValueName; + + public BindTagsToRegionalSecretTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new BindTagsToRegionalSecretSample(); + _tagKeysClient = TagKeysClient.Create(); + _tagValuesClient = TagValuesClient.Create(); + _tagBindingsClient = TagBindingsClient.Create(); + } + + private void CreateTagKeyAndValue(string projectId) + { + // Generate unique names for tag key and value + string tagKeyShortName = $"test-key-{_fixture.RandomId()}"; + string tagValueShortName = $"test-value-{_fixture.RandomId()}"; + + var createKeyRequest = new CreateTagKeyRequest + { + TagKey = new TagKey + { + Parent = $"projects/{projectId}", + ShortName = tagKeyShortName, + } + }; + + try + { + var createKeyOperation = _tagKeysClient.CreateTagKey(createKeyRequest); + TagKey tagKey = createKeyOperation.PollUntilCompleted().Result; + _tagKeyName = tagKey.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag key: " + e.Message, e); + } + + var createValueRequest = new CreateTagValueRequest + { + TagValue = new TagValue + { + Parent = _tagKeyName, + ShortName = tagValueShortName, + } + }; + + try + { + var createValueOperation = _tagValuesClient.CreateTagValue(createValueRequest); + TagValue tagValue = createValueOperation.PollUntilCompleted().Result; + _tagValueName = tagValue.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag value: " + e.Message, e); + } + } + + private void CleanupResources() + { + // Delete the tag value if it exists + if (!string.IsNullOrEmpty(_tagValueName)) + { + try + { + var deleteValueRequest = new DeleteTagValueRequest { Name = _tagValueName }; + _tagValuesClient.DeleteTagValue(deleteValueRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag value: {e.GetType().Name}: {e.Message}"); + } + } + + // Delete the tag key if it exists + if (!string.IsNullOrEmpty(_tagKeyName)) + { + try + { + var deleteKeyRequest = new DeleteTagKeyRequest { Name = _tagKeyName }; + _tagKeysClient.DeleteTagKey(deleteKeyRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag key: {e.GetType().Name}: {e.Message}"); + } + } + } + + [Fact] + public async Task BindsTagToRegionalSecretAsync() + { + // Create a tag key and value for testing + CreateTagKeyAndValue(_fixture.ProjectId); + + SecretName secretName = SecretName.FromProjectLocationSecret(_fixture.ProjectId, _fixture.LocationId, _fixture.RandomId()); + + // Call the method being tested + TagBinding tagBinding = await _sample.BindTagsToRegionalSecretAsync( + projectId: secretName.ProjectId, + locationId: secretName.LocationId, + secretId: secretName.SecretId, + tagValue: _tagValueName); + + Assert.Equal(_tagValueName, tagBinding.TagValue); + // Clean up all resources + _fixture.DeleteSecret(secretName); + CleanupResources(); + + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/BindTagToSecretTests.cs b/secretmanager/api/SecretManager.Samples.Tests/BindTagToSecretTests.cs new file mode 100644 index 00000000000..84e05349ff1 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/BindTagToSecretTests.cs @@ -0,0 +1,144 @@ +/* + * 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 + * + * 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.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.IO; +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class BindTagsToSecretTests +{ + private readonly SecretManagerFixture _fixture; + private readonly BindTagsToSecretSample _sample; + private readonly TagKeysClient _tagKeysClient; + private readonly TagValuesClient _tagValuesClient; + private readonly TagBindingsClient _tagBindingsClient; + private string _tagKeyName; + private string _tagValueName; + + public BindTagsToSecretTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new BindTagsToSecretSample(); + _tagKeysClient = TagKeysClient.Create(); + _tagValuesClient = TagValuesClient.Create(); + _tagBindingsClient = TagBindingsClient.Create(); + } + + private void CreateTagKeyAndValue(string projectId) + { + // Generate unique names for tag key and value + string tagKeyShortName = $"test-key-{_fixture.RandomId()}"; + string tagValueShortName = $"test-value-{_fixture.RandomId()}"; + + var createKeyRequest = new CreateTagKeyRequest + { + TagKey = new TagKey + { + Parent = $"projects/{projectId}", + ShortName = tagKeyShortName, + } + }; + + try + { + var createKeyOperation = _tagKeysClient.CreateTagKey(createKeyRequest); + TagKey tagKey = createKeyOperation.PollUntilCompleted().Result; + _tagKeyName = tagKey.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag key: " + e.Message, e); + } + + var createValueRequest = new CreateTagValueRequest + { + TagValue = new TagValue + { + Parent = _tagKeyName, + ShortName = tagValueShortName, + } + }; + + try + { + var createValueOperation = _tagValuesClient.CreateTagValue(createValueRequest); + TagValue tagValue = createValueOperation.PollUntilCompleted().Result; + _tagValueName = tagValue.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag value: " + e.Message, e); + } + } + + private void CleanupResources() + { + + // Delete the tag value if it exists + if (!string.IsNullOrEmpty(_tagValueName)) + { + try + { + var deleteValueRequest = new DeleteTagValueRequest { Name = _tagValueName }; + _tagValuesClient.DeleteTagValue(deleteValueRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag value: {e.GetType().Name}: {e.Message}"); + } + } + + // Delete the tag key if it exists + if (!string.IsNullOrEmpty(_tagKeyName)) + { + try + { + var deleteKeyRequest = new DeleteTagKeyRequest { Name = _tagKeyName }; + _tagKeysClient.DeleteTagKey(deleteKeyRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag key: {e.GetType().Name}: {e.Message}"); + } + } + } + + [Fact] + public async Task BindsTagToSecretAsync() + { + // Create a tag key and value for testing + CreateTagKeyAndValue(_fixture.ProjectId); + + // Generate a unique secret ID + SecretName secretName = new SecretName(_fixture.ProjectId, _fixture.RandomId()); + // string secretId = _fixture.RandomId(); + + TagBinding tagBinding = await _sample.BindTagsToSecretAsync( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + tagValue: _tagValueName); + + Assert.Equal(_tagValueName, tagBinding.TagValue); + + _fixture.DeleteSecret(secretName); + CleanupResources(); + + } +}; diff --git a/secretmanager/api/SecretManager.Samples.Tests/CreateRegionalSecretWithExpirationTests.cs b/secretmanager/api/SecretManager.Samples.Tests/CreateRegionalSecretWithExpirationTests.cs new file mode 100644 index 00000000000..cd96835d4b3 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/CreateRegionalSecretWithExpirationTests.cs @@ -0,0 +1,56 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class CreateRegionalSecretWithExpireTimeTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly CreateRegionalSecretWithExpireTimeSample _sample; + + public CreateRegionalSecretWithExpireTimeTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new CreateRegionalSecretWithExpireTimeSample(); + } + + [Fact] + public void CreatesRegionalSecretWithExpireTime() + { + // Get the SecretName from the set ProjectId & LocationId. + SecretName secretName = SecretName.FromProjectLocationSecret( + _fixture.ProjectId, _fixture.LocationId, _fixture.RandomId()); + try + { + // Run the code sample. + Secret result = _sample.CreateRegionalSecretWithExpireTime( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + locationId: secretName.LocationId); + + Assert.NotNull(result.ExpireTime); + } + finally + { + // Clean the created secret. + _fixture.DeleteSecret(secretName); + } + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/CreateRegionalSecretWithRotationTests.cs b/secretmanager/api/SecretManager.Samples.Tests/CreateRegionalSecretWithRotationTests.cs new file mode 100644 index 00000000000..5b04095212e --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/CreateRegionalSecretWithRotationTests.cs @@ -0,0 +1,70 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class CreateRegionalSecretWithRotationTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly CreateRegionalSecretWithRotationSample _sample; + + public CreateRegionalSecretWithRotationTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new CreateRegionalSecretWithRotationSample(); + } + + [Fact] + public void CreatesRegionalSecretWithRotation() + { + + // Get the SecretName from the set ProjectId & LocationId. + SecretName secretName = SecretName.FromProjectLocationSecret( + _fixture.ProjectId, _fixture.LocationId, _fixture.RandomId()); + + // Run the code sample + Secret result = _sample.CreateRegionalSecretWithRotation( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + locationId: secretName.LocationId, + topicName: _fixture.TopicName); + + // Verify rotation configuration + Assert.NotNull(result.Rotation); + Assert.NotNull(result.Rotation.NextRotationTime); + Assert.NotNull(result.Rotation.RotationPeriod); + Assert.Equal(86400, result.Rotation.RotationPeriod.Seconds); + + // Verify topic configuration + Assert.NotEmpty(result.Topics); + Assert.Contains(result.Topics, topic => topic.Name == _fixture.TopicName); + + // Verify next rotation time is in the future (approximately 24 hours from now) + DateTime nextRotation = result.Rotation.NextRotationTime.ToDateTime(); + DateTime now = DateTime.UtcNow; + TimeSpan difference = nextRotation - now; + + double differenceInMinutes = difference.TotalMinutes; + Assert.True(differenceInMinutes > 1438 && differenceInMinutes < 1442, + $"Next rotation time should be approximately 24 hours (1440 minutes) from now, but was {differenceInMinutes} minutes"); + + _fixture.DeleteSecret(secretName); + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/CreateRegionalSecretWithTopicTests.cs b/secretmanager/api/SecretManager.Samples.Tests/CreateRegionalSecretWithTopicTests.cs new file mode 100644 index 00000000000..b9c5c257fc6 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/CreateRegionalSecretWithTopicTests.cs @@ -0,0 +1,53 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using System; +using System.Linq; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class CreateRegionalSecretWithTopicTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly CreateRegionalSecretWithTopicSample _sample; + + public CreateRegionalSecretWithTopicTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new CreateRegionalSecretWithTopicSample(); + } + + [Fact] + public void CreatesRegionalSecretWithTopic() + { + // Get the SecretName from the set ProjectId & LocationId. + SecretName secretName = SecretName.FromProjectLocationSecret( + _fixture.ProjectId, _fixture.LocationId, _fixture.RandomId()); + // Create a regional secret with topic notification + Secret createdSecret = _sample.CreateRegionalSecretWithTopic( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + locationId: secretName.LocationId, + topicName: _fixture.TopicName); + + // Verify the topic was configured + Assert.NotEmpty(createdSecret.Topics); + Assert.Contains(createdSecret.Topics, topic => topic.Name == _fixture.TopicName); + + _fixture.DeleteSecret(secretName); + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/CreateSecretWithExpirationTests.cs b/secretmanager/api/SecretManager.Samples.Tests/CreateSecretWithExpirationTests.cs new file mode 100644 index 00000000000..6929350720d --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/CreateSecretWithExpirationTests.cs @@ -0,0 +1,54 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class CreateSecretWithExpirationTests +{ + private readonly SecretManagerFixture _fixture; + private readonly CreateSecretWithExpirationSample _sample; + + public CreateSecretWithExpirationTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new CreateSecretWithExpirationSample(); + } + + [Fact] + public void CreatesSecretWithExpiration() + { + // Get the SecretName to create Secret. + SecretName secretName = new SecretName(_fixture.ProjectId, _fixture.RandomId()); + try + { + // Create the secret with expiration. + Secret result = _sample.CreateSecretWithExpiration( + projectId: secretName.ProjectId, secretId: secretName.SecretId); + + Assert.NotNull(result.ExpireTime); + } + finally + { + // Clean the created secret. + _fixture.DeleteSecret(secretName); + } + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/CreateSecretWithRotationTests.cs b/secretmanager/api/SecretManager.Samples.Tests/CreateSecretWithRotationTests.cs new file mode 100644 index 00000000000..b20f3a0ed49 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/CreateSecretWithRotationTests.cs @@ -0,0 +1,70 @@ +/* + * 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 + * + * 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.Iam.V1; +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class CreateSecretWithRotationTests +{ + private readonly SecretManagerFixture _fixture; + private readonly CreateSecretWithRotationSample _sample; + + public CreateSecretWithRotationTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new CreateSecretWithRotationSample(); + } + + [Fact] + public void CreatesSecretWithRotation() + { + // Get the SecretName to create Secret + SecretName secretName = new SecretName(_fixture.ProjectId, _fixture.RandomId()); + + // Create the secret with rotation configuration + Secret result = _sample.CreateSecretWithRotation( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + topicName: _fixture.TopicName); + + // Verify rotation configuration + Assert.NotNull(result.Rotation); + Assert.NotNull(result.Rotation.NextRotationTime); + Assert.NotNull(result.Rotation.RotationPeriod); + Assert.Equal(86400, result.Rotation.RotationPeriod.Seconds); + + // Verify topic configuration + Assert.NotEmpty(result.Topics); + Assert.Contains(result.Topics, topic => topic.Name == _fixture.TopicName); + + // Verify next rotation time is in the future (approximately 24 hours from now) + DateTime nextRotation = result.Rotation.NextRotationTime.ToDateTime(); + DateTime now = DateTime.UtcNow; + TimeSpan difference = nextRotation - now; + + double differenceInMinutes = difference.TotalMinutes; + Assert.True(differenceInMinutes > 1438 && differenceInMinutes < 1442, + $"Next rotation time should be approximately 24 hours (1440 minutes) from now, but was {differenceInMinutes} minutes"); + + _fixture.DeleteSecret(secretName); + + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/CreateSecretWithTopicTests.cs b/secretmanager/api/SecretManager.Samples.Tests/CreateSecretWithTopicTests.cs new file mode 100644 index 00000000000..96e4a778542 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/CreateSecretWithTopicTests.cs @@ -0,0 +1,52 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using System; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class CreateSecretWithTopicTests +{ + private readonly SecretManagerFixture _fixture; + private readonly CreateSecretWithTopicSample _sample; + + public CreateSecretWithTopicTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new CreateSecretWithTopicSample(); + } + + [Fact] + public void CreatesSecretWithTopic() + { + // Get the SecretName to create Secret + SecretName secretName = new SecretName(_fixture.ProjectId, _fixture.RandomId()); + + // Create the secret with topic configuration + Secret result = _sample.CreateSecretWithTopic( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + topicName: _fixture.TopicName); + + // Verify topic configuration + Assert.NotEmpty(result.Topics); + Assert.Single(result.Topics); + Assert.Equal(_fixture.TopicName, result.Topics[0].Name); + + _fixture.DeleteSecret(secretName); + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretAnnotationTests.cs b/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretAnnotationTests.cs new file mode 100644 index 00000000000..850c2d75ed3 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretAnnotationTests.cs @@ -0,0 +1,63 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class DeleteRegionalSecretAnnotationTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly DeleteRegionalSecretAnnotationSample _sample; + + public DeleteRegionalSecretAnnotationTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new DeleteRegionalSecretAnnotationSample(); + } + + [Fact] + public void DeleteRegionalSecretAnnotation() + { + // Create a secret with annotations + Secret secret = _fixture.CreateSecret(_fixture.RandomId()); + SecretName secretName = secret.SecretName; + try + { + // Get a key from the existing annotations + string annotationKey = _fixture.AnnotationKey; + + // Verify the secret has annotations + Assert.NotEmpty(secret.Annotations); + Assert.True(secret.Annotations.ContainsKey(annotationKey)); + + // Run the sample code to delete the annotation + Secret result = _sample.DeleteRegionalSecretAnnotation( + projectId: secretName.ProjectId, + locationId: secretName.LocationId, + secretId: secretName.SecretId); + + Assert.Empty(result.Annotations); + } + finally + { + // Clean the created secret. + _fixture.DeleteSecret(secretName); + } + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretExpirationTests.cs b/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretExpirationTests.cs new file mode 100644 index 00000000000..0604bbde140 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretExpirationTests.cs @@ -0,0 +1,55 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class DeleteRegionalSecretExpirationTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly DeleteRegionalSecretExpirationSample _deleteSample; + + public DeleteRegionalSecretExpirationTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _deleteSample = new DeleteRegionalSecretExpirationSample(); + } + + [Fact] + public void DeletesRegionalSecretExpiration() + { + Secret initialSecret = _fixture.CreateSecretWithExpireTime(); + try + { + // Delete the expiration time + Secret result = _deleteSample.DeleteRegionalSecretExpiration( + projectId: initialSecret.SecretName.ProjectId, + secretId: initialSecret.SecretName.SecretId, + locationId: initialSecret.SecretName.LocationId); + + Assert.Null(result.ExpireTime); + } + finally + { + // Clean the created secret + _fixture.DeleteSecret(initialSecret.SecretName); + } + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretLabelTests.cs b/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretLabelTests.cs new file mode 100644 index 00000000000..6c52ee3cae7 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretLabelTests.cs @@ -0,0 +1,59 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class DeleteRegionalSecretLabelTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly DeleteRegionalSecretLabelSample _sample; + + public DeleteRegionalSecretLabelTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new DeleteRegionalSecretLabelSample(); + } + + [Fact] + public void DeleteRegionalSecretLabel() + { + Secret secret = _fixture.CreateSecret(_fixture.RandomId()); + SecretName secretName = secret.SecretName; + try + { + // Verify the secret has labels + Assert.NotEmpty(secret.Labels); + + // Run the sample code to delete all labels + Secret result = _sample.DeleteRegionalSecretLabel( + + projectId: secretName.ProjectId, + locationId: secretName.LocationId, + secretId: secretName.SecretId); + + Assert.Empty(result.Labels); + } + finally + { + // Clean the created secret. + _fixture.DeleteSecret(secretName); + } + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretRotationTests.cs b/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretRotationTests.cs new file mode 100644 index 00000000000..2409505f970 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/DeleteRegionalSecretRotationTests.cs @@ -0,0 +1,63 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class DeleteRegionalSecretRotationTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly DeleteRegionalSecretRotationSample _deleteSample; + + public DeleteRegionalSecretRotationTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _deleteSample = new DeleteRegionalSecretRotationSample(); + } + + [Fact] + public void DeletesRegionalSecretRotation() + { + // First create a regional secret with rotation + Secret createdSecret = _fixture.CreateSecretWithRotation(); + + // Verify the secret has rotation configuration + Assert.NotNull(createdSecret.Rotation); + Assert.NotEqual(0, createdSecret.Rotation.RotationPeriod.Seconds); + Assert.NotNull(createdSecret.Rotation.NextRotationTime); + + // Delete rotation configuration using our sample + Secret updatedSecret = _deleteSample.DeleteRegionalSecretRotation( + projectId: createdSecret.SecretName.ProjectId, + secretId: createdSecret.SecretName.SecretId, + locationId: createdSecret.SecretName.LocationId); + + // Verify rotation configuration was removed + // The rotation field should either be null or have default values + if (updatedSecret.Rotation != null) + { + // If not null, verify it has default/empty values + Assert.Equal(0, updatedSecret.Rotation.RotationPeriod.Seconds); + Assert.Equal(0, updatedSecret.Rotation.NextRotationTime.Seconds); + } + + // Clean up + _fixture.DeleteSecret(createdSecret.SecretName); + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretAnnotationTests.cs b/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretAnnotationTests.cs new file mode 100644 index 00000000000..b7ffc00c47c --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretAnnotationTests.cs @@ -0,0 +1,57 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class DeleteSecretAnnotationTests +{ + private readonly SecretManagerFixture _fixture; + private readonly DeleteSecretAnnotationSample _sample; + + public DeleteSecretAnnotationTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new DeleteSecretAnnotationSample(); + } + + [Fact] + public void DeleteSecretAnnotation() + { + // Create the secret. + Secret secret = _fixture.CreateSecret(_fixture.RandomId()); + // Get the secretName from the created secret. + SecretName secretName = secret.SecretName; + try + { + Assert.NotEmpty(secret.Annotations); + // Call the code sample function to delete the annotations + Secret result = _sample.DeleteSecretAnnotation( + projectId: secretName.ProjectId, secretId: secretName.SecretId); + + // Assert that the label is deleted. + Assert.Empty(result.Annotations); + } + finally + { + // Clean the created secret. + _fixture.DeleteSecret(secretName); + } + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretExpirationTests.cs b/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretExpirationTests.cs new file mode 100644 index 00000000000..191aca84657 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretExpirationTests.cs @@ -0,0 +1,54 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class DeleteSecretExpirationTests +{ + private readonly SecretManagerFixture _fixture; + private readonly DeleteSecretExpirationSample _deleteSample; + + public DeleteSecretExpirationTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _deleteSample = new DeleteSecretExpirationSample(); + } + + [Fact] + public void DeletesSecretExpiration() + { + // First, create a secret with an expiration time + Secret secret = _fixture.CreateSecretWithExpiration(); + try + { + // Delete the expiration time + Secret result = _deleteSample.DeleteSecretExpiration( + projectId: secret.SecretName.ProjectId, secretId: secret.SecretName.SecretId); + + Assert.Null(result.ExpireTime); + } + finally + { + // Clean up the created secret + _fixture.DeleteSecret(secret.SecretName); + } + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretLabelTests.cs b/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretLabelTests.cs new file mode 100644 index 00000000000..7bc8bee0c03 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretLabelTests.cs @@ -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 + * + * 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.SecretManager.V1; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class DeleteSecretLabelTests +{ + private readonly SecretManagerFixture _fixture; + private readonly DeleteSecretLabelSample _sample; + + public DeleteSecretLabelTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new DeleteSecretLabelSample(); + } + + [Fact] + public void DeleteSecretLabel() + { + // Create the secret. + Secret secret = _fixture.CreateSecret(_fixture.RandomId()); + + // Get the secretName from the created secret. + SecretName secretName = secret.SecretName; + try + { + Assert.NotEmpty(secret.Labels); + // Call the code sample function to delete the label + Secret result = _sample.DeleteSecretLabel( + projectId: secretName.ProjectId, secretId: secretName.SecretId); + + // Assert that the label is deleted. + Assert.Empty(result.Labels); + } + finally + { + // Clean the created secret. + _fixture.DeleteSecret(secretName); + } + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretRotationTests.cs b/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretRotationTests.cs new file mode 100644 index 00000000000..1eb78039796 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/DeleteSecretRotationTests.cs @@ -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 + * + * 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.SecretManager.V1; +using System; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class DeleteSecretRotationTests +{ + private readonly SecretManagerFixture _fixture; + private readonly DeleteSecretRotationSample _deleteSample; + + public DeleteSecretRotationTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _deleteSample = new DeleteSecretRotationSample(); + } + + [Fact] + public void DeletesSecretRotation() + { + // First create a secret with rotation (24 hours by default) + Secret createdSecret = _fixture.CreateSecretWithRotation(); + + // Verify initial rotation configuration exists + Assert.NotNull(createdSecret.Rotation); + Assert.NotNull(createdSecret.Rotation.RotationPeriod); + Assert.NotNull(createdSecret.Rotation.NextRotationTime); + + // Delete the rotation configuration + Secret updatedSecret = _deleteSample.DeleteSecretRotation( + projectId: createdSecret.SecretName.ProjectId, + secretId: createdSecret.SecretName.SecretId); + + // Verify the rotation configuration was removed + Assert.Null(updatedSecret.Rotation); + + // Verify the topic configuration was preserved + Assert.NotEmpty(updatedSecret.Topics); + Assert.Contains(updatedSecret.Topics, topic => topic.Name == _fixture.TopicName); + + _fixture.DeleteSecret(createdSecret.SecretName); + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/DetachRegionalTagBindingTests.cs b/secretmanager/api/SecretManager.Samples.Tests/DetachRegionalTagBindingTests.cs new file mode 100644 index 00000000000..7c1ba31c951 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/DetachRegionalTagBindingTests.cs @@ -0,0 +1,162 @@ +/* + * 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 + * + * 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.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.IO; +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class DetachTagFromRegionalSecretTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly BindTagsToRegionalSecretSample _bindSample; + private readonly DetachTagFromRegionalSecretSample _detachSample; + private readonly ListRegionalSecretTagBindingsSample _listSample; + private readonly TagKeysClient _tagKeysClient; + private readonly TagValuesClient _tagValuesClient; + private string _tagKeyName; + private string _tagValueName; + + public DetachTagFromRegionalSecretTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _bindSample = new BindTagsToRegionalSecretSample(); + _detachSample = new DetachTagFromRegionalSecretSample(); + _listSample = new ListRegionalSecretTagBindingsSample(); + _tagKeysClient = TagKeysClient.Create(); + _tagValuesClient = TagValuesClient.Create(); + } + + private void CreateTagKeyAndValue(string projectId) + { + // Generate unique names for tag key and value + string tagKeyShortName = $"test-key-{_fixture.RandomId()}"; + string tagValueShortName = $"test-value-{_fixture.RandomId()}"; + + var createKeyRequest = new CreateTagKeyRequest + { + TagKey = new TagKey + { + Parent = $"projects/{projectId}", + ShortName = tagKeyShortName, + } + }; + + try + { + var createKeyOperation = _tagKeysClient.CreateTagKey(createKeyRequest); + TagKey tagKey = createKeyOperation.PollUntilCompleted().Result; + _tagKeyName = tagKey.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag key: " + e.Message, e); + } + + var createValueRequest = new CreateTagValueRequest + { + TagValue = new TagValue + { + Parent = _tagKeyName, + ShortName = tagValueShortName, + } + }; + + try + { + var createValueOperation = _tagValuesClient.CreateTagValue(createValueRequest); + TagValue tagValue = createValueOperation.PollUntilCompleted().Result; + _tagValueName = tagValue.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag value: " + e.Message, e); + } + } + + private void CleanupResource() + { + + // Delete the tag value + if (!string.IsNullOrEmpty(_tagValueName)) + { + try + { + var deleteValueRequest = new DeleteTagValueRequest { Name = _tagValueName }; + _tagValuesClient.DeleteTagValue(deleteValueRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag value: {e.GetType().Name}: {e.Message}"); + } + } + + // Delete the tag key + if (!string.IsNullOrEmpty(_tagKeyName)) + { + try + { + var deleteKeyRequest = new DeleteTagKeyRequest { Name = _tagKeyName }; + _tagKeysClient.DeleteTagKey(deleteKeyRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag key: {e.GetType().Name}: {e.Message}"); + } + } + } + + [Fact] + public async Task DetachesTagFromRegionalSecret() + { + // Create a tag key and value for testing + CreateTagKeyAndValue(_fixture.ProjectId); + + SecretName secretName = SecretName.FromProjectLocationSecret(_fixture.ProjectId, _fixture.LocationId, _fixture.RandomId()); + + // Create a regional secret and bind the tag to it + await _bindSample.BindTagsToRegionalSecretAsync( + projectId: secretName.ProjectId, + locationId: secretName.LocationId, + secretId: secretName.SecretId, + tagValue: _tagValueName); + + + // Detach the tag + string bindingName = await _detachSample.DetachTagFromRegionalSecretAsync( + projectId: secretName.ProjectId, + locationId: secretName.LocationId, + secretId: secretName.SecretId, + tagValue: _tagValueName); + + Assert.NotEmpty(bindingName); + + bindingName = await _detachSample.DetachTagFromRegionalSecretAsync( + projectId: secretName.ProjectId, + locationId: secretName.LocationId, + secretId: secretName.SecretId, + tagValue: _tagValueName); + + Assert.Empty(bindingName); + + // Clean up all resources + _fixture.DeleteSecret(secretName); + CleanupResource(); + } +}; diff --git a/secretmanager/api/SecretManager.Samples.Tests/DetachTagBindingTests.cs b/secretmanager/api/SecretManager.Samples.Tests/DetachTagBindingTests.cs new file mode 100644 index 00000000000..cc6ef2cdcc3 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/DetachTagBindingTests.cs @@ -0,0 +1,169 @@ +/* + * 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 + * + * 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.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class DetachTagTests +{ + private readonly SecretManagerFixture _fixture; + private readonly DetachTagSample _detachSample; + private readonly BindTagsToSecretSample _bindSample; + private readonly TagKeysClient _tagKeysClient; + private readonly TagValuesClient _tagValuesClient; + private readonly TagBindingsClient _tagBindingsClient; + private readonly ListTagBindingsSample _listSample; + private string _tagKeyName; + private string _tagValueName; + + public DetachTagTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _detachSample = new DetachTagSample(); + _bindSample = new BindTagsToSecretSample(); + _tagKeysClient = TagKeysClient.Create(); + _tagValuesClient = TagValuesClient.Create(); + _tagBindingsClient = TagBindingsClient.Create(); + } + + private void CreateTagKeyAndValue(string projectId) + { + // Generate unique names for tag key and value + string tagKeyShortName = $"test-key-{_fixture.RandomId()}"; + string tagValueShortName = $"test-value-{_fixture.RandomId()}"; + + var createKeyRequest = new CreateTagKeyRequest + { + TagKey = new TagKey + { + Parent = $"projects/{projectId}", + ShortName = tagKeyShortName, + } + }; + + try + { + var createKeyOperation = _tagKeysClient.CreateTagKey(createKeyRequest); + TagKey tagKey = createKeyOperation.PollUntilCompleted().Result; + _tagKeyName = tagKey.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag key: " + e.Message, e); + } + + var createValueRequest = new CreateTagValueRequest + { + TagValue = new TagValue + { + Parent = _tagKeyName, + ShortName = tagValueShortName, + } + }; + + try + { + var createValueOperation = _tagValuesClient.CreateTagValue(createValueRequest); + TagValue tagValue = createValueOperation.PollUntilCompleted().Result; + _tagValueName = tagValue.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag value: " + e.Message, e); + } + } + + private void CleanupResources() + { + // Delete the tag value if it exists + if (!string.IsNullOrEmpty(_tagValueName)) + { + try + { + var deleteValueRequest = new DeleteTagValueRequest { Name = _tagValueName }; + _tagValuesClient.DeleteTagValue(deleteValueRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag value: {e.GetType().Name}: {e.Message}"); + } + } + + // Delete the tag key if it exists + if (!string.IsNullOrEmpty(_tagKeyName)) + { + try + { + var deleteKeyRequest = new DeleteTagKeyRequest { Name = _tagKeyName }; + _tagKeysClient.DeleteTagKey(deleteKeyRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag key: {e.GetType().Name}: {e.Message}"); + } + } + } + + [Fact] + public async Task DetachesTagFromSecret() + { + + // Create a tag key and value for testing + CreateTagKeyAndValue(_fixture.ProjectId); + + SecretName secretName = new SecretName(_fixture.ProjectId, _fixture.RandomId()); + + // Use the BindTagsToSecret sample to create a secret and bind a tag to it + await _bindSample.BindTagsToSecretAsync( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + tagValue: _tagValueName); + + // Verify the binding exists + SecretManagerServiceClient secretClient = SecretManagerServiceClient.Create(); + string resource = $"//secretmanager.googleapis.com/{secretName}"; + + // Capture console output for the detach operation + StringWriter sw = new StringWriter(); + Console.SetOut(sw); + + // Call the method being tested + string bindingName = await _detachSample.DetachTagAsync( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + tagValue: _tagValueName); + + Assert.NotEmpty(bindingName); + + bindingName = await _detachSample.DetachTagAsync( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + tagValue: _tagValueName); + + Assert.Empty(bindingName); + // Clean up all resources + _fixture.DeleteSecret(secretName); + CleanupResources(); + + } +}; diff --git a/secretmanager/api/SecretManager.Samples.Tests/EditSecretLabelTests.cs b/secretmanager/api/SecretManager.Samples.Tests/EditSecretLabelTests.cs new file mode 100644 index 00000000000..6da6560a7dd --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/EditSecretLabelTests.cs @@ -0,0 +1,46 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class EditSecretLabelTests +{ + private readonly SecretManagerFixture _fixture; + private readonly EditSecretLabelSample _sample; + + public EditSecretLabelTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new EditSecretLabelSample(); + } + + [Fact] + public void EditSecretLabel() + { + // Get the SecretName to create Secret. + SecretName secretName = _fixture.Secret.SecretName; + + // Call the code sample function. + Secret result = _sample.EditSecretLabel( + projectId: secretName.ProjectId, secretId: secretName.SecretId); + + Assert.Equal("my-label-value", result.Labels["my-label-key"]); + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/ListRegionalTagBindingsTests.cs b/secretmanager/api/SecretManager.Samples.Tests/ListRegionalTagBindingsTests.cs new file mode 100644 index 00000000000..9ef7dc28c48 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/ListRegionalTagBindingsTests.cs @@ -0,0 +1,155 @@ +/* + * 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 + * + * 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.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class ListRegionalTagBindingsTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly BindTagsToRegionalSecretSample _bindSample; + private readonly ListRegionalSecretTagBindingsSample _listSample; + private readonly TagKeysClient _tagKeysClient; + private readonly TagValuesClient _tagValuesClient; + private readonly TagBindingsClient _tagBindingsClient; + private string _tagKeyName; + private string _tagValueName; + + public ListRegionalTagBindingsTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _bindSample = new BindTagsToRegionalSecretSample(); + _listSample = new ListRegionalSecretTagBindingsSample(); + _tagKeysClient = TagKeysClient.Create(); + _tagValuesClient = TagValuesClient.Create(); + _tagBindingsClient = TagBindingsClient.Create(); + } + + private void CreateTagKeyAndValue(string projectId) + { + // Generate unique names for tag key and value + string tagKeyShortName = $"test-key-{_fixture.RandomId()}"; + string tagValueShortName = $"test-value-{_fixture.RandomId()}"; + + var createKeyRequest = new CreateTagKeyRequest + { + TagKey = new TagKey + { + Parent = $"projects/{projectId}", + ShortName = tagKeyShortName, + } + }; + + try + { + var createKeyOperation = _tagKeysClient.CreateTagKey(createKeyRequest); + TagKey tagKey = createKeyOperation.PollUntilCompleted().Result; + _tagKeyName = tagKey.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag key: " + e.Message, e); + } + + var createValueRequest = new CreateTagValueRequest + { + TagValue = new TagValue + { + Parent = _tagKeyName, + ShortName = tagValueShortName, + } + }; + + try + { + var createValueOperation = _tagValuesClient.CreateTagValue(createValueRequest); + TagValue tagValue = createValueOperation.PollUntilCompleted().Result; + _tagValueName = tagValue.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag value: " + e.Message, e); + } + } + + private void CleanupResources() + { + + // Delete the tag value if it exists + if (!string.IsNullOrEmpty(_tagValueName)) + { + try + { + var deleteValueRequest = new DeleteTagValueRequest { Name = _tagValueName }; + _tagValuesClient.DeleteTagValue(deleteValueRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag value: {e.GetType().Name}: {e.Message}"); + } + } + + // Delete the tag key if it exists + if (!string.IsNullOrEmpty(_tagKeyName)) + { + try + { + var deleteKeyRequest = new DeleteTagKeyRequest { Name = _tagKeyName }; + _tagKeysClient.DeleteTagKey(deleteKeyRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag key: {e.GetType().Name}: {e.Message}"); + } + } + } + [Fact] + public async Task ListsRegionalSecretTagBindings() + { + + // Create a tag key and two values for testing + CreateTagKeyAndValue(_fixture.ProjectId); + + SecretName secretName = SecretName.FromProjectLocationSecret(_fixture.ProjectId, _fixture.LocationId, _fixture.RandomId()); + + // Create a regional secret and bind the first tag to it + await _bindSample.BindTagsToRegionalSecretAsync( + projectId: secretName.ProjectId, + locationId: secretName.LocationId, + secretId: secretName.SecretId, + tagValue: _tagValueName); + + // Call the method being tested + List tagBindings = _listSample.ListRegionalSecretTagBindings( + projectId: secretName.ProjectId, + locationId: secretName.LocationId, + secretId: secretName.SecretId); + + Assert.Single(tagBindings); + Assert.Equal(_tagValueName, tagBindings[0].TagValue); + + // Clean up all resources + _fixture.DeleteSecret(secretName); + CleanupResources(); + } +}; diff --git a/secretmanager/api/SecretManager.Samples.Tests/ListSecretVersionsWithFilterTests.cs b/secretmanager/api/SecretManager.Samples.Tests/ListSecretVersionsWithFilterTests.cs new file mode 100644 index 00000000000..cd50cced3e8 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/ListSecretVersionsWithFilterTests.cs @@ -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 + * + * 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 System; +using System.IO; +using System.Collections.Generic; +using Xunit; +using Google.Cloud.SecretManager.V1; + +[Collection(nameof(SecretManagerFixture))] +public class ListSecretVersionsWithFilterTests +{ + private readonly SecretManagerFixture _fixture; + private readonly ListSecretVersionsWithFilterSample _sample; + + public ListSecretVersionsWithFilterTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new ListSecretVersionsWithFilterSample(); + } + + [Fact] + public void ListSecretVersionsWithFilter() + { + // Create the secret resource. + Secret secret = _fixture.CreateSecret(_fixture.RandomId()); + + // Get the SecretName. + SecretName secretName = secret.SecretName; + + // Run the code sample. + SecretVersion secretVersion = _fixture.AddSecretVersion(secret); + _fixture.DisableSecretVersion(secretVersion); + + // Run the sample code + IList versions = _sample.ListSecretVersionsWithFilter( + projectId: secretName.ProjectId, + secretId: secretName.SecretId); + + // Verify we got results + Assert.NotNull(versions); + Assert.NotEmpty(versions); + + // Verify only disabled versions are returned + foreach (var version in versions) + { + Assert.Equal(SecretVersion.Types.State.Disabled, version.State); + } + + // Clean the created secret. + _fixture.DeleteSecret(secretName); + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/ListSecretsWithFilterTests.cs b/secretmanager/api/SecretManager.Samples.Tests/ListSecretsWithFilterTests.cs new file mode 100644 index 00000000000..058bf163ccd --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/ListSecretsWithFilterTests.cs @@ -0,0 +1,59 @@ +/* + * 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 + * + * 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 System; +using System.IO; +using System.Collections.Generic; +using Xunit; +using Google.Cloud.SecretManager.V1; +using System.Linq; + +[Collection(nameof(SecretManagerFixture))] +public class ListSecretsWithFilterTests +{ + private readonly SecretManagerFixture _fixture; + private readonly ListSecretsWithFilterSample _sample; + + public ListSecretsWithFilterTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new ListSecretsWithFilterSample(); + } + + [Fact] + public void ListsSecretsWithFilter() + { + Secret secret = _fixture.CreateSecret(_fixture.RandomId()); + SecretName secretName = secret.SecretName; + try + { + IList secrets = _sample.ListSecretsWithFilter( + projectId: _fixture.ProjectId); + + // Verify we got results + Assert.NotNull(secrets); + Assert.NotEmpty(secrets); + + // Verify our specific secret is in the results + bool foundSecret = secrets.Any(s => s.SecretName.SecretId == secretName.SecretId); + Assert.True(foundSecret, $"The secret {secretName.SecretId} with label my-label-key=my-label-value should be in the results"); + } + finally + { + _fixture.DeleteSecret(secretName); + } + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/ListTagBindingsTests.cs b/secretmanager/api/SecretManager.Samples.Tests/ListTagBindingsTests.cs new file mode 100644 index 00000000000..255727db3be --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/ListTagBindingsTests.cs @@ -0,0 +1,154 @@ +/* + * 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 + * + * 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.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class ListTagBindingsTests +{ + private readonly SecretManagerFixture _fixture; + private readonly ListTagBindingsSample _listSample; + private readonly BindTagsToSecretSample _bindSample; + private readonly TagKeysClient _tagKeysClient; + private readonly TagValuesClient _tagValuesClient; + private readonly TagBindingsClient _tagBindingsClient; + private string _tagKeyName; + private string _tagValueName; + + public ListTagBindingsTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _listSample = new ListTagBindingsSample(); + _bindSample = new BindTagsToSecretSample(); + _tagKeysClient = TagKeysClient.Create(); + _tagValuesClient = TagValuesClient.Create(); + _tagBindingsClient = TagBindingsClient.Create(); + } + + private void CreateTagKeyAndValue(string projectId) + { + // Generate unique names for tag key and value + string tagKeyShortName = $"test-key-{_fixture.RandomId()}"; + string tagValueShortName = $"test-value-{_fixture.RandomId()}"; + + var createKeyRequest = new CreateTagKeyRequest + { + TagKey = new TagKey + { + Parent = $"projects/{projectId}", + ShortName = tagKeyShortName, + } + }; + + try + { + var createKeyOperation = _tagKeysClient.CreateTagKey(createKeyRequest); + TagKey tagKey = createKeyOperation.PollUntilCompleted().Result; + _tagKeyName = tagKey.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag key: " + e.Message, e); + } + + var createValueRequest = new CreateTagValueRequest + { + TagValue = new TagValue + { + Parent = _tagKeyName, + ShortName = tagValueShortName, + } + }; + + try + { + var createValueOperation = _tagValuesClient.CreateTagValue(createValueRequest); + TagValue tagValue = createValueOperation.PollUntilCompleted().Result; + _tagValueName = tagValue.Name; + } + catch (Exception e) + { + throw new Exception("Error creating tag value: " + e.Message, e); + } + } + + private void CleanupResources() + { + + // Delete the tag value if it exists + if (!string.IsNullOrEmpty(_tagValueName)) + { + try + { + var deleteValueRequest = new DeleteTagValueRequest { Name = _tagValueName }; + _tagValuesClient.DeleteTagValue(deleteValueRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag value: {e.GetType().Name}: {e.Message}"); + } + } + + // Delete the tag key if it exists + if (!string.IsNullOrEmpty(_tagKeyName)) + { + try + { + var deleteKeyRequest = new DeleteTagKeyRequest { Name = _tagKeyName }; + _tagKeysClient.DeleteTagKey(deleteKeyRequest).PollUntilCompleted(); + } + catch (Exception e) + { + Console.WriteLine($"Error deleting tag key: {e.GetType().Name}: {e.Message}"); + } + } + } + + [Fact] + public async Task ListsTagBindingsAsync() + { + // Create a tag key and value for testing + CreateTagKeyAndValue(_fixture.ProjectId); + + SecretName secretName = new SecretName(_fixture.ProjectId, _fixture.RandomId()); + + // Use the BindTagsToSecret sample to create a secret and bind a tag to it + await _bindSample.BindTagsToSecretAsync( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + tagValue: _tagValueName); + + IList tagBindings = new List(); + + // Call the method being tested + tagBindings = _listSample.ListTagBindings( + projectId: secretName.ProjectId, + secretId: secretName.SecretId); + + Assert.Single(tagBindings); + Assert.Equal(_tagValueName, tagBindings[0].TagValue); + + // Clean up all resources + _fixture.DeleteSecret(secretName); + CleanupResources(); + } +}; diff --git a/secretmanager/api/SecretManager.Samples.Tests/RegionalSecretManagerFixture.cs b/secretmanager/api/SecretManager.Samples.Tests/RegionalSecretManagerFixture.cs index 6451b6c97cc..2bd079d3f3b 100644 --- a/secretmanager/api/SecretManager.Samples.Tests/RegionalSecretManagerFixture.cs +++ b/secretmanager/api/SecretManager.Samples.Tests/RegionalSecretManagerFixture.cs @@ -32,6 +32,9 @@ public class RegionalSecretManagerFixture : IDisposable, ICollectionFixture - + diff --git a/secretmanager/api/SecretManager.Samples.Tests/SecretManagerFixture.cs b/secretmanager/api/SecretManager.Samples.Tests/SecretManagerFixture.cs index 82fa8d99691..ae246721c3f 100644 --- a/secretmanager/api/SecretManager.Samples.Tests/SecretManagerFixture.cs +++ b/secretmanager/api/SecretManager.Samples.Tests/SecretManagerFixture.cs @@ -34,6 +34,8 @@ public class SecretManagerFixture : IDisposable, ICollectionFixture topic.Name == _fixture.TopicName); + + _fixture.DeleteSecret(createdSecret.SecretName); + + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/createRegionalSecretWithCmekTests.cs b/secretmanager/api/SecretManager.Samples.Tests/createRegionalSecretWithCmekTests.cs new file mode 100644 index 00000000000..aa3f071a79a --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/createRegionalSecretWithCmekTests.cs @@ -0,0 +1,62 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(RegionalSecretManagerFixture))] +public class CreateRegionalSecretWithCmekTests +{ + private readonly RegionalSecretManagerFixture _fixture; + private readonly CreateRegionalSecretWithCmekSample _sample; + + public CreateRegionalSecretWithCmekTests(RegionalSecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new CreateRegionalSecretWithCmekSample(); + } + + [Fact] + public void CreatesRegionalSecretWithCmek() + { + // Skip the test if no regional KMS key is available + if (string.IsNullOrEmpty(_fixture.KmsKeyName)) + { + return; + } + + // Get the SecretName from the set ProjectId & LocationId. + SecretName secretName = SecretName.FromProjectLocationSecret(_fixture.ProjectId, _fixture.LocationId, _fixture.RandomId()); + try + { + // Create the regional secret with CMEK. + Secret result = _sample.CreateRegionalSecretWithCmek( + projectId: secretName.ProjectId, + locationId: secretName.LocationId, + secretId: secretName.SecretId, + kmsKeyName: _fixture.KmsKeyName); + + Assert.Equal(result.CustomerManagedEncryption.KmsKeyName, _fixture.KmsKeyName); + } + finally + { + // Clean the created secret. + _fixture.DeleteSecret(secretName); + } + } +} diff --git a/secretmanager/api/SecretManager.Samples.Tests/createSecretWithCmekTests.cs b/secretmanager/api/SecretManager.Samples.Tests/createSecretWithCmekTests.cs new file mode 100644 index 00000000000..4f5caf14534 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples.Tests/createSecretWithCmekTests.cs @@ -0,0 +1,63 @@ +/* + * 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 + * + * 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.SecretManager.V1; +using Microsoft.VisualBasic; +using System; +using System.IO; +using Xunit; + +[Collection(nameof(SecretManagerFixture))] +public class CreateSecretWithCmekTests +{ + private readonly SecretManagerFixture _fixture; + private readonly CreateSecretWithCmekSample _sample; + + public CreateSecretWithCmekTests(SecretManagerFixture fixture) + { + _fixture = fixture; + _sample = new CreateSecretWithCmekSample(); + } + + [Fact] + public void CreatesSecretWithCmek() + { + // Skip the test if no KMS key is available + if (string.IsNullOrEmpty(_fixture.KmsKeyName)) + { + return; + } + + // Get the SecretName to create Secret. + SecretName secretName = new SecretName(_fixture.ProjectId, _fixture.RandomId()); + try + { + // Create the secret with CMEK. + Secret result = _sample.CreateSecretWithCmek( + projectId: secretName.ProjectId, + secretId: secretName.SecretId, + kmsKeyName: _fixture.KmsKeyName); + + Assert.Equal(result.Replication.Automatic.CustomerManagedEncryption.KmsKeyName, _fixture.KmsKeyName); + } + finally + { + // Clean the created secret. + _fixture.DeleteSecret(secretName); + } + + } +} diff --git a/secretmanager/api/SecretManager.Samples/BindTagToRegionalSecret.cs b/secretmanager/api/SecretManager.Samples/BindTagToRegionalSecret.cs new file mode 100644 index 00000000000..20a9f930a30 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/BindTagToRegionalSecret.cs @@ -0,0 +1,83 @@ +/* + * 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 + * + * 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 secretmanager_bind_tags_to_regional_secret] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.Threading.Tasks; + +public class BindTagsToRegionalSecretSample +{ + + public async Task BindTagsToRegionalSecretAsync( + string projectId = "my-project", + string locationId = "us-central1", + string secretId = "my-secret", + string tagValue = "tagValues/123456789012") + { + // Create the Regional Secret Manager Client. + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Build the parent resource name. + LocationName location = new LocationName(projectId, locationId); + + // Build the secret. + Secret secret = new Secret(); + + // Call the API to create the secret. + Secret createdSecret = client.CreateSecret(location, secretId, secret); + + // Print the new secret name. + Console.WriteLine($"Created regional secret: {createdSecret.Name}"); + string resourceManagerApiEndpoint = $"{locationId}-cloudresourcemanager.googleapis.com"; + + // Create the resource manager client + TagBindingsClientBuilder tagBindingsClientBuilder = new TagBindingsClientBuilder + { + Endpoint = resourceManagerApiEndpoint + }; + + TagBindingsClient resourceManagerClient = tagBindingsClientBuilder.Build(); + + // Create the tag binding + CreateTagBindingRequest request = new CreateTagBindingRequest + { + TagBinding = new TagBinding + { + Parent = $"//secretmanager.googleapis.com/{createdSecret.Name}", + TagValue = tagValue + } + }; + + // Create the tag binding + var operation = await resourceManagerClient.CreateTagBindingAsync(request); + + // Wait for the operation to complete + await operation.PollUntilCompletedAsync(); + TagBinding tagBinding = operation.Result; + + // Print the tag binding. + Console.WriteLine($"Created tag binding: {tagBinding.Name}"); + return tagBinding; + } +} +// [END secretmanager_bind_tags_to_regional_secret] diff --git a/secretmanager/api/SecretManager.Samples/BindTagToSecret.cs b/secretmanager/api/SecretManager.Samples/BindTagToSecret.cs new file mode 100644 index 00000000000..3e84c7387bd --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/BindTagToSecret.cs @@ -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 + * + * 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 secretmanager_bind_tags_to_secret] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.Threading.Tasks; + +public class BindTagsToSecretSample +{ + public async Task BindTagsToSecretAsync( + string projectId = "my-project", + string secretId = "my-secret", + string tagValue = "tagValues/123456789012") + { + // Create the Secret Manager client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the parent resource name. + ProjectName projectName = new ProjectName(projectId); + + // Build the secret. + Secret secret = new Secret + { + Replication = new Replication + { + Automatic = new Replication.Types.Automatic(), + }, + }; + + // Call the API. + Secret createdSecret = client.CreateSecret(projectName, secretId, secret); + + // Print the new secret name. + Console.WriteLine($"Created secret: {createdSecret.Name}"); + + // Create the resource manager client. + TagBindingsClient resourceManagerClient = TagBindingsClient.Create(); + + // Format the resource name for the secret. + string resourceName = $"//secretmanager.googleapis.com/{createdSecret.Name}"; + + // Create the tag binding. + TagBinding tagBinding = new TagBinding + { + Parent = resourceName, + TagValue = tagValue + }; + + // Create the tag binding and wait for the operation to complete. + var operation = await resourceManagerClient.CreateTagBindingAsync(tagBinding); + await operation.PollUntilCompletedAsync(); + TagBinding tagBindingResult = operation.Result; + + Console.WriteLine($"Created Tag Binding: {tagBindingResult.Name}"); + return tagBindingResult; + } +} +// [END secretmanager_bind_tags_to_secret] diff --git a/secretmanager/api/SecretManager.Samples/CreateRegionalSecretWithExpiration.cs b/secretmanager/api/SecretManager.Samples/CreateRegionalSecretWithExpiration.cs new file mode 100644 index 00000000000..5dcd9c28ca7 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/CreateRegionalSecretWithExpiration.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 secretmanager_create_regional_secret_with_expire_time] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class CreateRegionalSecretWithExpireTimeSample +{ + public Secret CreateRegionalSecretWithExpireTime( + string projectId = "my-project", + string secretId = "my-secret-with-expiry", + string locationId = "us-central1") + { + // Set expiration time to 1 hour from now + DateTime expireTime = DateTime.UtcNow.AddHours(1); + + // Create the Regional Secret Manager Client. + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Build the parent resource name. + LocationName location = new LocationName(projectId, locationId); + + // Convert DateTime to Timestamp + Timestamp timestamp = Timestamp.FromDateTime(expireTime); + + // Build the secret with expiration time + Secret secret = new Secret + { + ExpireTime = timestamp + }; + + // Call the API. + Secret createdSecret = client.CreateSecret(location, secretId, secret); + + Console.WriteLine($"Created secret {createdSecret.SecretName} with expiration time {expireTime}"); + return createdSecret; + } +} +// [END secretmanager_create_regional_secret_with_expire_time] diff --git a/secretmanager/api/SecretManager.Samples/CreateRegionalSecretWithRotation.cs b/secretmanager/api/SecretManager.Samples/CreateRegionalSecretWithRotation.cs new file mode 100644 index 00000000000..47194e98395 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/CreateRegionalSecretWithRotation.cs @@ -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 + * + * 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 secretmanager_create_regional_secret_with_rotation] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class CreateRegionalSecretWithRotationSample +{ + public Secret CreateRegionalSecretWithRotation( + string projectId = "my-project", + string secretId = "my-secret-with-rotation", + string locationId = "us-central1", + string topicName = "projects/my-project/topics/my-topic") + { + // Set rotation period to 24 hours + int rotationPeriodHours = 24; + + // Set next rotation time to 24 hours from now + DateTime nextRotationTime = DateTime.UtcNow.AddHours(24); + + // Create the Regional Secret Manager Client. + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Build the parent resource name. + LocationName location = new LocationName(projectId, locationId); + + // Convert DateTime to Timestamp for next rotation time + Timestamp nextRotationTimestamp = Timestamp.FromDateTime(nextRotationTime.ToUniversalTime()); + + // Convert rotation period to protobuf Duration + Duration rotationPeriod = new Duration + { + Seconds = rotationPeriodHours * 3600 // Convert hours to seconds + }; + + // Build the secret with rotation configuration and topic + Secret secret = new Secret + { + Topics = { new Topic { Name = topicName } }, + Rotation = new Rotation + { + NextRotationTime = nextRotationTimestamp, + RotationPeriod = rotationPeriod + } + }; + + // Call the API. + Secret createdSecret = client.CreateSecret(location, secretId, secret); + + Console.WriteLine($"Created secret {createdSecret.SecretName} with rotation period {rotationPeriodHours} hours and topic {topicName}"); + + return createdSecret; + } +} +// [END secretmanager_create_regional_secret_with_rotation] diff --git a/secretmanager/api/SecretManager.Samples/CreateRegionalSecretWithTopic.cs b/secretmanager/api/SecretManager.Samples/CreateRegionalSecretWithTopic.cs new file mode 100644 index 00000000000..65aa3e67587 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/CreateRegionalSecretWithTopic.cs @@ -0,0 +1,53 @@ +/* + * 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 + * + * 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 secretmanager_create_regional_secret_with_topic] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using System; + +public class CreateRegionalSecretWithTopicSample +{ + public Secret CreateRegionalSecretWithTopic( + string projectId = "my-project", + string secretId = "my-secret-with-topic", + string locationId = "us-central1", + string topicName = "projects/my-project/topics/my-topic") + { + // Create the Regional Secret Manager Client + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Build the resource name of the parent project with location + LocationName parent = new LocationName(projectId, locationId); + + // Create the secret with a topic for notifications + Secret secretToCreate = new Secret + { + Topics = { new Topic { Name = topicName } } + }; + + // Create the secret + Secret createdSecret = client.CreateSecret(parent, secretId, secretToCreate); + + Console.WriteLine($"Created secret {createdSecret.Name} with topic {topicName}"); + return createdSecret; + } +} +// [END secretmanager_create_regional_secret_with_topic] diff --git a/secretmanager/api/SecretManager.Samples/CreateSecretWithExpiration.cs b/secretmanager/api/SecretManager.Samples/CreateSecretWithExpiration.cs new file mode 100644 index 00000000000..fc756e54951 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/CreateSecretWithExpiration.cs @@ -0,0 +1,57 @@ +/* + * 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 + * + * 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 secretmanager_create_secret_with_expiration] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class CreateSecretWithExpirationSample +{ + public Secret CreateSecretWithExpiration(string projectId = "my-project", string secretId = "my-secret-with-expiry") + { + // Calculate expiration time (1 hour from now) + DateTime expireTime = DateTime.UtcNow.AddHours(1); + + // Create the client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the parent resource name. + ProjectName projectName = new ProjectName(projectId); + + // Convert DateTime to Timestamp + Timestamp timestamp = Timestamp.FromDateTime(expireTime); + + // Build the secret with automatic replication and expiration time. + Secret secret = new Secret + { + Replication = new Replication + { + Automatic = new Replication.Types.Automatic(), + }, + ExpireTime = timestamp + }; + + // Call the API. + Secret createdSecret = client.CreateSecret(projectName, secretId, secret); + + Console.WriteLine($"Created secret {createdSecret.SecretName} with expiration time {expireTime}"); + return createdSecret; + } +} +// [END secretmanager_create_secret_with_expiration] diff --git a/secretmanager/api/SecretManager.Samples/CreateSecretWithRotation.cs b/secretmanager/api/SecretManager.Samples/CreateSecretWithRotation.cs new file mode 100644 index 00000000000..0fbf7763f6e --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/CreateSecretWithRotation.cs @@ -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 + * + * 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 secretmanager_create_secret_with_rotation] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class CreateSecretWithRotationSample +{ + public Secret CreateSecretWithRotation( + string projectId = "my-project", + string secretId = "my-rotating-secret", + string topicName = "projects/my-project/topics/my-rotation-topic") + { + // Set rotation period to 24 hours + int rotationPeriodHours = 24; + + // Calculate next rotation time (24 hours from now) + DateTime nextRotationTime = DateTime.UtcNow.AddHours(24); + + // Create the client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the parent resource name. + ProjectName projectName = new ProjectName(projectId); + + // Convert rotation period to protobuf Duration + Duration rotationPeriod = new Duration + { + Seconds = rotationPeriodHours * 3600 // Convert hours to seconds + }; + + // Convert DateTime to Timestamp for next rotation time + Timestamp nextRotationTimestamp = Timestamp.FromDateTime(nextRotationTime.ToUniversalTime()); + + // Build the secret with automatic replication and rotation configuration. + Secret secret = new Secret + { + Replication = new Replication + { + Automatic = new Replication.Types.Automatic(), + }, + Topics = { new Topic { Name = topicName } }, + Rotation = new Rotation + { + NextRotationTime = nextRotationTimestamp, + RotationPeriod = rotationPeriod + } + }; + + // Call the API. + Secret createdSecret = client.CreateSecret(projectName, secretId, secret); + + Console.WriteLine($"Created secret {createdSecret.SecretName} with rotation period {rotationPeriodHours} hours and topic {topicName}"); + + return createdSecret; + } +} +// [END secretmanager_create_secret_with_rotation] diff --git a/secretmanager/api/SecretManager.Samples/CreateSecretWithTopic.cs b/secretmanager/api/SecretManager.Samples/CreateSecretWithTopic.cs new file mode 100644 index 00000000000..f53566aba35 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/CreateSecretWithTopic.cs @@ -0,0 +1,54 @@ +/* + * 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 + * + * 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 secretmanager_create_secret_with_topic] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using System; + +public class CreateSecretWithTopicSample +{ + public Secret CreateSecretWithTopic( + string projectId = "my-project", + string secretId = "my-secret-with-notifications", + string topicName = "projects/my-project/topics/my-secret-topic") + { + // Create the client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the parent resource name. + ProjectName projectName = new ProjectName(projectId); + + // Build the secret with automatic replication and topic configuration. + Secret secret = new Secret + { + Replication = new Replication + { + Automatic = new Replication.Types.Automatic() + }, + Topics = { new Topic { Name = topicName } } + }; + + // Call the API. + Secret createdSecret = client.CreateSecret(projectName, secretId, secret); + + Console.WriteLine($"Created secret {createdSecret.SecretName} with topic {topicName}"); + + return createdSecret; + } +} +// [END secretmanager_create_secret_with_topic] diff --git a/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretAnnotation.cs b/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretAnnotation.cs new file mode 100644 index 00000000000..6cca53a2f8f --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretAnnotation.cs @@ -0,0 +1,56 @@ +/* + * 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 + * + * 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 secretmanager_delete_regional_secret_annotation] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class DeleteRegionalSecretAnnotationSample +{ + public Secret DeleteRegionalSecretAnnotation( + string projectId = "my-project", + string locationId = "my-location", + string secretId = "my-secret") + { + // Create the Regional Secret Manager Client. + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Build the resource name of the secret. + SecretName secretName = SecretName.FromProjectLocationSecret(projectId, locationId, secretId); + + // Get the secret. + Secret secret = client.GetSecret(secretName); + + // Delete the annotation + secret.Annotations.Clear(); + + // Build the field mask. + FieldMask updateMask = FieldMask.FromString("annotations"); + + // Update the secret. + Secret updatedSecret = client.UpdateSecret(secret, updateMask); + + // Print the new secret name. + Console.WriteLine($"Updated secret: {updatedSecret.Name}"); + return updatedSecret; + } +} +// [END secretmanager_delete_regional_secret_annotation] diff --git a/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretExpiration.cs b/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretExpiration.cs new file mode 100644 index 00000000000..2840f865e49 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretExpiration.cs @@ -0,0 +1,55 @@ +/* + * 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 + * + * 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 secretmanager_delete_regional_secret_expiration] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class DeleteRegionalSecretExpirationSample +{ + public Secret DeleteRegionalSecretExpiration( + string projectId = "my-project", + string secretId = "my-secret", + string locationId = "us-central1") + { + // Create the Regional Secret Manager Client. + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Build the secret name + SecretName secretName = SecretName.FromProjectLocationSecret(projectId, locationId, secretId); + + // Build the secret with no ExpireTime set (which will clear it) + Secret secret = new Secret + { + SecretName = secretName, + }; + + // Build the field mask for the fields to update + FieldMask updateMask = new FieldMask { Paths = { "expire_time" } }; + + // Update the secret to remove the expiration time + Secret updatedSecret = client.UpdateSecret(secret, updateMask); + + Console.WriteLine($"Removed expiration from secret {updatedSecret.SecretName}"); + return updatedSecret; + } +} +// [END secretmanager_delete_regional_secret_expiration] diff --git a/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretLabel.cs b/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretLabel.cs new file mode 100644 index 00000000000..f9ec0746e8c --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretLabel.cs @@ -0,0 +1,56 @@ +/* + * 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 + * + * 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 secretmanager_delete_regional_secret_label] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class DeleteRegionalSecretLabelSample +{ + public Secret DeleteRegionalSecretLabel( + string projectId = "my-project", + string locationId = "my-location", + string secretId = "my-secret") + { + // Create the Regional Secret Manager Client. + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Build the resource name of the secret. + SecretName secretName = SecretName.FromProjectLocationSecret(projectId, locationId, secretId); + + // Get the secret. + Secret secret = client.GetSecret(secretName); + + // Clear all labels + secret.Labels.Clear(); + + // Build the field mask. + FieldMask updateMask = FieldMask.FromString("labels"); + + // Update the secret. + Secret updatedSecret = client.UpdateSecret(secret, updateMask); + + // Print the new secret name. + Console.WriteLine($"Updated secret: {updatedSecret.Name}"); + return updatedSecret; + } +} +// [END secretmanager_delete_regional_secret_label] diff --git a/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretRotation.cs b/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretRotation.cs new file mode 100644 index 00000000000..07f8da7502d --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/DeleteRegionalSecretRotation.cs @@ -0,0 +1,59 @@ +/* + * 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 + * + * 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 secretmanager_delete_regional_secret_rotation] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class DeleteRegionalSecretRotationSample +{ + public Secret DeleteRegionalSecretRotation( + string projectId = "my-project", + string secretId = "my-secret-with-rotation", + string locationId = "us-central1") + { + // Construct the secret name from the component parts + string secretName = $"projects/{projectId}/locations/{locationId}/secrets/{secretId}"; + + // Create the Regional Secret Manager Client + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Create a field mask to update only the rotation field + FieldMask updateMask = new FieldMask { Paths = { "rotation" } }; + + // Create the secret object with just the name + Secret secret = new Secret + { + Name = secretName + }; + + // Update the secret to remove the rotation configuration + Secret result = client.UpdateSecret(new UpdateSecretRequest + { + Secret = secret, + UpdateMask = updateMask + }); + + Console.WriteLine($"Removed rotation from secret {result.Name}"); + return result; + } +} +// [END secretmanager_delete_regional_secret_rotation] diff --git a/secretmanager/api/SecretManager.Samples/DeleteSecretAnnotation.cs b/secretmanager/api/SecretManager.Samples/DeleteSecretAnnotation.cs new file mode 100644 index 00000000000..778f32b2c3c --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/DeleteSecretAnnotation.cs @@ -0,0 +1,51 @@ +/* + * 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 + * + * 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 secretmanager_delete_secret_annotation] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class DeleteSecretAnnotationSample +{ + public Secret DeleteSecretAnnotation( + string projectId = "my-project", string secretId = "my-secret") + { + // Create the client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the resource name of the secret. + SecretName secretName = new SecretName(projectId, secretId); + + // Get the secret. + Secret secret = client.GetSecret(secretName); + + // Clear all annotations + secret.Annotations.Clear(); + + // Build the field mask. + FieldMask updateMask = FieldMask.FromString("annotations"); + + // Update the secret. + Secret updatedSecret = client.UpdateSecret(secret, updateMask); + + // Print the new secret name. + Console.WriteLine($"Updated secret: {updatedSecret.Name}"); + return updatedSecret; + } +} +// [END secretmanager_delete_secret_annotation] diff --git a/secretmanager/api/SecretManager.Samples/DeleteSecretExpiration.cs b/secretmanager/api/SecretManager.Samples/DeleteSecretExpiration.cs new file mode 100644 index 00000000000..7a47c90e80c --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/DeleteSecretExpiration.cs @@ -0,0 +1,50 @@ +/* + * 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 + * + * 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 secretmanager_delete_secret_expiration] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class DeleteSecretExpirationSample +{ + public Secret DeleteSecretExpiration(string projectId = "my-project", string secretId = "my-secret-with-expiration") + { + // Create the client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the resource name of the secret. + SecretName secretName = new SecretName(projectId, secretId); + + // Create the secret with the expire_time field explicitly set to null + Secret secret = new Secret + { + SecretName = secretName, + // ExpireTime is not set, which will clear it + }; + + // Create the update mask for the fields to update + FieldMask updateMask = new FieldMask { Paths = { "expire_time" } }; + + // Update the secret + Secret updatedSecret = client.UpdateSecret(secret, updateMask); + + Console.WriteLine($"Removed expiration from secret {updatedSecret.SecretName}"); + return updatedSecret; + } +} +// [END secretmanager_delete_secret_expiration] diff --git a/secretmanager/api/SecretManager.Samples/DeleteSecretLabel.cs b/secretmanager/api/SecretManager.Samples/DeleteSecretLabel.cs new file mode 100644 index 00000000000..1be1d78d131 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/DeleteSecretLabel.cs @@ -0,0 +1,51 @@ +/* + * 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 + * + * 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 secretmanager_delete_secret_label] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class DeleteSecretLabelSample +{ + public Secret DeleteSecretLabel( + string projectId = "my-project", string secretId = "my-secret") + { + // Create the client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the resource name of the secret. + SecretName secretName = new SecretName(projectId, secretId); + + // Get the secret. + Secret secret = client.GetSecret(secretName); + + // Clear all labels + secret.Labels.Clear(); + + // Build the field mask. + FieldMask updateMask = FieldMask.FromString("labels"); + + // Update the secret. + Secret updatedSecret = client.UpdateSecret(secret, updateMask); + + // Print the new secret name. + Console.WriteLine($"Updated secret: {updatedSecret.Name}"); + return updatedSecret; + } +} +// [END secretmanager_delete_secret_label] diff --git a/secretmanager/api/SecretManager.Samples/DeleteSecretRotation.cs b/secretmanager/api/SecretManager.Samples/DeleteSecretRotation.cs new file mode 100644 index 00000000000..ba2b7bdd32d --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/DeleteSecretRotation.cs @@ -0,0 +1,55 @@ +/* + * 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 + * + * 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 secretmanager_delete_secret_rotation] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class DeleteSecretRotationSample +{ + public Secret DeleteSecretRotation(string projectId = "my-project", string secretId = "my-secret-with-rotation") + { + // Create the client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the resource name of the secret. + SecretName secretName = new SecretName(projectId, secretId); + + // Create the update mask to remove the rotation field. + FieldMask updateMask = new FieldMask { Paths = { "rotation" } }; + + // Build the secret with empty fields (will be removed by the update mask). + Secret secretToUpdate = new Secret + { + SecretName = secretName + }; + + // Call the API. + Secret updatedSecret = client.UpdateSecret(new UpdateSecretRequest + { + Secret = secretToUpdate, + UpdateMask = updateMask + }); + + Console.WriteLine($"Removed rotation from secret {updatedSecret.SecretName}"); + + return updatedSecret; + } +} +// [END secretmanager_delete_secret_rotation] diff --git a/secretmanager/api/SecretManager.Samples/DetachRegionalTagBinding.cs b/secretmanager/api/SecretManager.Samples/DetachRegionalTagBinding.cs new file mode 100644 index 00000000000..0bbfa2e30f7 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/DetachRegionalTagBinding.cs @@ -0,0 +1,85 @@ +/* + * 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 + * + * 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 secretmanager_detach_tag_from_regional_secret] + +using Google.Cloud.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.Linq; +using System.Threading.Tasks; + +public class DetachTagFromRegionalSecretSample +{ + public async Task DetachTagFromRegionalSecretAsync( + string projectId = "my-project", + string locationId = "us-central1", + string secretId = "my-secret", + string tagValue = "tagValues/123456789012") + { + // Set up the endpoint for the regional resource manager + string rmEndpoint = $"{locationId}-cloudresourcemanager.googleapis.com"; + + // Create the Tag Bindings client with the regional endpoint + TagBindingsClient tagBindingsClient = new TagBindingsClientBuilder + { + Endpoint = rmEndpoint + }.Build(); + + // Build the secret name + string name = $"projects/{projectId}/locations/{locationId}/secrets/{secretId}"; + + // Format the resource name for the secret + string resourceName = $"//secretmanager.googleapis.com/{name}"; + + // List all tag bindings for the secret to find the one to detach + ListTagBindingsRequest listRequest = new ListTagBindingsRequest + { + Parent = resourceName + }; + + // Find the binding that matches the tag value + TagBinding bindingToDelete = null; + foreach (var binding in tagBindingsClient.ListTagBindings(listRequest)) + { + if (binding.TagValue == tagValue) + { + bindingToDelete = binding; + break; + } + } + + if (bindingToDelete == null) + { + Console.WriteLine($"No tag binding found for tag value {tagValue} on {name}"); + return ""; + } + + // Create the delete request + DeleteTagBindingRequest deleteRequest = new DeleteTagBindingRequest + { + Name = bindingToDelete.Name + }; + + // Delete the tag binding and wait for the operation to complete + var operation = await tagBindingsClient.DeleteTagBindingAsync(deleteRequest); + await operation.PollUntilCompletedAsync(); + + Console.WriteLine($"Detached tag value {tagValue} from {name}"); + return bindingToDelete.Name; + } +} +// [END secretmanager_detach_tag_from_regional_secret] diff --git a/secretmanager/api/SecretManager.Samples/DetachTagBinding.cs b/secretmanager/api/SecretManager.Samples/DetachTagBinding.cs new file mode 100644 index 00000000000..5a359b39994 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/DetachTagBinding.cs @@ -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 + * + * 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 secretmanager_detach_tag] + +using Google.Cloud.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.Threading.Tasks; + +public class DetachTagSample +{ + public async Task DetachTagAsync( + string projectId = "my-project", + string secretId = "my-secret", + string tagValue = "tagValues/123456789012") + { + // Create the Resource Manager client. + TagBindingsClient rmClient = TagBindingsClient.Create(); + + // Create the Secret Manager client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the resource name of the parent secret. + SecretName secretName = new SecretName(projectId, secretId); + + // Format the parent resource for tag bindings. + string parent = $"//secretmanager.googleapis.com/{secretName}"; + + // Find the binding name for the given tag value + string bindingName = null; + ListTagBindingsRequest listRequest = new ListTagBindingsRequest + { + Parent = parent + }; + + // Search for the binding with the specified tag value + var bindings = rmClient.ListTagBindings(listRequest); + foreach (var binding in bindings) + { + if (binding.TagValue == tagValue) + { + bindingName = binding.Name; + break; + } + } + + if (bindingName == null) + { + Console.WriteLine($"Tag binding for value {tagValue} not found on {secretName}."); + return ""; + } + + // Delete the tag binding + DeleteTagBindingRequest deleteRequest = new DeleteTagBindingRequest + { + Name = bindingName + }; + + // Delete the binding and wait for the operation to complete + var operation = await rmClient.DeleteTagBindingAsync(deleteRequest); + await operation.PollUntilCompletedAsync(); + + Console.WriteLine($"Detached tag value {tagValue} from {secretName}"); + return bindingName; + } +} +// [END secretmanager_detach_tag] diff --git a/secretmanager/api/SecretManager.Samples/EditSecretLabel.cs b/secretmanager/api/SecretManager.Samples/EditSecretLabel.cs new file mode 100644 index 00000000000..71f73db0677 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/EditSecretLabel.cs @@ -0,0 +1,54 @@ +/* + * 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 + * + * 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 secretmanager_edit_secret_label] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; +using System.Collections.Generic; + +public class EditSecretLabelSample +{ + public Secret EditSecretLabel( + string projectId = "my-project", string secretId = "my-secret") + { + string labelKey = "my-label-key"; + string labelValue = "my-label-value"; + // Create the Secret Manager client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the resource name of the secret. + SecretName name = new SecretName(projectId, secretId); + + // Get the secret. + Secret secret = client.GetSecret(name); + + // Update the labels + secret.Labels[labelKey] = labelValue; + + // Update the secret. + FieldMask updateMask = FieldMask.FromString("labels"); + + // Call the API. + Secret updatedSecret = client.UpdateSecret(secret, updateMask); + + // Print the new secret name. + Console.WriteLine($"Updated secret: {updatedSecret.Name}"); + return updatedSecret; + } +} +// [END secretmanager_edit_secret_label] diff --git a/secretmanager/api/SecretManager.Samples/ListRegionalTagBindings.cs b/secretmanager/api/SecretManager.Samples/ListRegionalTagBindings.cs new file mode 100644 index 00000000000..d31cc5a19f2 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/ListRegionalTagBindings.cs @@ -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 + * + * 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 secretmanager_list_regional_secret_tag_bindings] + +using Google.Cloud.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +public class ListRegionalSecretTagBindingsSample +{ + public List ListRegionalSecretTagBindings( + string projectId = "my-project", + string locationId = "us-central1", + string secretId = "my-regional-secret") + { + // Set up the endpoint for the regional resource manager + string rmEndpoint = $"{locationId}-cloudresourcemanager.googleapis.com"; + + // Create the Tag Bindings client with the regional endpoint + TagBindingsClient tagBindingsClient = new TagBindingsClientBuilder + { + Endpoint = rmEndpoint + }.Build(); + + string name = $"projects/{projectId}/locations/{locationId}/secrets/{secretId}"; + + // Format the parent resource for the tag bindings request + string parent = $"//secretmanager.googleapis.com/{name}"; + + // List the tag bindings + Console.WriteLine($"Tag bindings for {name}:"); + bool foundBindings = false; + + // Use the ListTagBindings method to get all tag bindings + ListTagBindingsRequest request = new ListTagBindingsRequest + { + Parent = parent + }; + + List tagBindings = new List(); + // Iterate through the results + foreach (var binding in tagBindingsClient.ListTagBindings(request)) + { + Console.WriteLine($"- Tag Value: {binding.TagValue}"); + foundBindings = true; + tagBindings.Add(binding); + } + + if (!foundBindings) + { + Console.WriteLine($"No tag bindings found for {name}."); + } + return tagBindings; + } +} +// [END secretmanager_list_regional_secret_tag_bindings] diff --git a/secretmanager/api/SecretManager.Samples/ListSecretVersionsWithFilter.cs b/secretmanager/api/SecretManager.Samples/ListSecretVersionsWithFilter.cs new file mode 100644 index 00000000000..9468d3af6ab --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/ListSecretVersionsWithFilter.cs @@ -0,0 +1,54 @@ +/* + * 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 + * + * 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 secretmanager_list_secret_versions_with_filter] + +using Google.Cloud.SecretManager.V1; +using System; +using System.Collections.Generic; + +public class ListSecretVersionsWithFilterSample +{ + public IList ListSecretVersionsWithFilter( + string projectId = "my-project", + string secretId = "my-secret" + ) + { + string filterStr = "state:DISABLED"; + // Create the Secret Manager client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the resource name of the parent secret. + SecretName secretName = new SecretName(projectId, secretId); + + // Create the request with filter. + ListSecretVersionsRequest request = new ListSecretVersionsRequest + { + ParentAsSecretName = secretName, + Filter = filterStr + }; + + List secretVersions = new List(); + // List all secret versions with the provided filter. + foreach (SecretVersion version in client.ListSecretVersions(request)) + { + Console.WriteLine($"Found secret version: {version.Name}"); + secretVersions.Add(version); + } + return secretVersions; + } +} +// [END secretmanager_list_secret_versions_with_filter] diff --git a/secretmanager/api/SecretManager.Samples/ListSecretsWithFilter.cs b/secretmanager/api/SecretManager.Samples/ListSecretsWithFilter.cs new file mode 100644 index 00000000000..c4e4274cef4 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/ListSecretsWithFilter.cs @@ -0,0 +1,53 @@ +/* + * 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 + * + * 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 secretmanager_list_secrets_with_filter] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using System; +using System.Collections.Generic; + +public class ListSecretsWithFilterSample +{ + public IList ListSecretsWithFilter(string projectId = "my-project") + { + string filterStr = "labels.my-label-key=my-label-value"; + // Create the Secret Manager client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the resource name of the parent project. + ProjectName projectName = new ProjectName(projectId); + ListSecretsRequest request = new ListSecretsRequest + { + ParentAsProjectName = projectName, + Filter = filterStr + }; + + // Create a list to hold the secrets + List secrets = new List(); + + // List all secrets with the provided filter. + foreach (Secret secret in client.ListSecrets(request)) + { + Console.WriteLine($"Found secret: {secret.Name}"); + secrets.Add(secret); + } + + return secrets; + } +} +// [END secretmanager_list_secrets_with_filter] diff --git a/secretmanager/api/SecretManager.Samples/ListTagBindings.cs b/secretmanager/api/SecretManager.Samples/ListTagBindings.cs new file mode 100644 index 00000000000..513712db66f --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/ListTagBindings.cs @@ -0,0 +1,65 @@ +/* + * 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 + * + * 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 secretmanager_list_tag_bindings] + +using Google.Cloud.ResourceManager.V3; +using Google.Cloud.SecretManager.V1; +using System; +using System.Collections.Generic; + +public class ListTagBindingsSample +{ + public IList ListTagBindings( + string projectId = "my-project", + string secretId = "my-secret") + { + // Create the Resource Manager client. + TagBindingsClient client = TagBindingsClient.Create(); + + // Build the resource name of the parent secret. + SecretName secretName = new SecretName(projectId, secretId); + + // Format the parent resource for tag bindings. + string parent = $"//secretmanager.googleapis.com/{secretName}"; + + // Create the request. + ListTagBindingsRequest request = new ListTagBindingsRequest + { + Parent = parent + }; + + // List all tag bindings. + var bindings = client.ListTagBindings(request); + bool foundBindings = false; + + Console.WriteLine($"Tag bindings for {secretName}:"); + List tagBindings = new List(); + foreach (var binding in bindings) + { + Console.WriteLine($"- Tag Value: {binding.TagValue}"); + foundBindings = true; + tagBindings.Add(binding); + } + + if (!foundBindings) + { + Console.WriteLine($"No tag bindings found for {secretName}."); + } + return tagBindings; + } +} +// [END secretmanager_list_tag_bindings] diff --git a/secretmanager/api/SecretManager.Samples/SecretManager.Samples.csproj b/secretmanager/api/SecretManager.Samples/SecretManager.Samples.csproj index 85fcc1a2b63..33887a8a06d 100644 --- a/secretmanager/api/SecretManager.Samples/SecretManager.Samples.csproj +++ b/secretmanager/api/SecretManager.Samples/SecretManager.Samples.csproj @@ -5,6 +5,7 @@ + diff --git a/secretmanager/api/SecretManager.Samples/UpdateRegionalSecretExpiration.cs b/secretmanager/api/SecretManager.Samples/UpdateRegionalSecretExpiration.cs new file mode 100644 index 00000000000..71afada1fc4 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/UpdateRegionalSecretExpiration.cs @@ -0,0 +1,62 @@ +/* + * 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 + * + * 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 secretmanager_update_regional_secret_expiration] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class UpdateRegionalSecretExpirationSample +{ + public Secret UpdateRegionalSecretExpiration( + string projectId = "my-project", + string secretId = "my-secret", + string locationId = "us-central1") + { + // Set new expiration time to 2 hours from now + DateTime newExpireTime = DateTime.UtcNow.AddHours(2); + + // Create the Regional Secret Manager Client. + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Build the secret name + SecretName secretName = SecretName.FromProjectLocationSecret(projectId, locationId, secretId); + + // Convert DateTime to Timestamp + Timestamp timestamp = Timestamp.FromDateTime(newExpireTime); + + // Build the secret with the new expiration time + Secret secret = new Secret + { + SecretName = secretName, + ExpireTime = timestamp + }; + + // Build the field mask for the fields to update + FieldMask updateMask = new FieldMask { Paths = { "expire_time" } }; + + // Update the secret + Secret updatedSecret = client.UpdateSecret(secret, updateMask); + + Console.WriteLine($"Updated secret {updatedSecret.SecretName} expiration time to {newExpireTime}"); + return updatedSecret; + } +} +// [END secretmanager_update_regional_secret_expiration] diff --git a/secretmanager/api/SecretManager.Samples/UpdateRegionalSecretRotation.cs b/secretmanager/api/SecretManager.Samples/UpdateRegionalSecretRotation.cs new file mode 100644 index 00000000000..fee8e38fe24 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/UpdateRegionalSecretRotation.cs @@ -0,0 +1,71 @@ +/* + * 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 + * + * 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 secretmanager_update_regional_secret_rotation_period] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class UpdateRegionalSecretRotationSample +{ + public Secret UpdateRegionalSecretRotationPeriod( + string projectId = "my-project", + string secretId = "my-secret", + string locationId = "us-central1") + { + // Build the secret name + SecretName secretName = SecretName.FromProjectLocationSecret(projectId, locationId, secretId); + + // Set updated rotation period to 48 hours + int newRotationPeriodHours = 48; + + // Create the Regional Secret Manager Client with the specific endpoint + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Create duration for the rotation period (48 hours in seconds) + Duration rotationPeriod = new Duration + { + Seconds = newRotationPeriodHours * 3600 // Convert hours to seconds + }; + + // Create a field mask to update only the rotation_period field + FieldMask updateMask = new FieldMask { Paths = { "rotation.rotation_period" } }; + + // Update the secret with the new rotation period + Secret secret = new Secret + { + SecretName = secretName, + Rotation = new Rotation + { + RotationPeriod = rotationPeriod + } + }; + + // Call the API + Secret result = client.UpdateSecret(secret, updateMask); + + // Get the rotation period in hours for display + double rotationHours = result.Rotation.RotationPeriod.Seconds / 3600.0; + + Console.WriteLine($"Updated secret {result.Name} rotation period to {rotationHours} hours"); + return result; + } +} +// [END secretmanager_update_regional_secret_rotation_period] diff --git a/secretmanager/api/SecretManager.Samples/UpdateSecretExpiration.cs b/secretmanager/api/SecretManager.Samples/UpdateSecretExpiration.cs new file mode 100644 index 00000000000..0b80912e5ad --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/UpdateSecretExpiration.cs @@ -0,0 +1,56 @@ +/* + * 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 + * + * 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 secretmanager_update_secret_expiration] + +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class UpdateSecretExpirationSample +{ + public Secret UpdateSecretExpiration(string projectId = "my-project", string secretId = "my-secret-with-expiration") + { + // Calculate new expiration time (2 hours from now) + DateTime newExpireTime = DateTime.UtcNow.AddHours(2); + + // Create the client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the resource name of the secret. + SecretName secretName = new SecretName(projectId, secretId); + + // Convert DateTime to Timestamp + Timestamp timestamp = Timestamp.FromDateTime(newExpireTime); + + // Create the secret to update with the new expiration time + Secret secret = new Secret + { + SecretName = secretName, + ExpireTime = timestamp + }; + + // Create the update mask for the fields to update + FieldMask updateMask = new FieldMask { Paths = { "expire_time" } }; + + // Update the secret + Secret updatedSecret = client.UpdateSecret(secret, updateMask); + + Console.WriteLine($"Updated secret {updatedSecret.SecretName} expiration time to {newExpireTime}"); + return updatedSecret; + } +} +// [END secretmanager_update_secret_expiration] diff --git a/secretmanager/api/SecretManager.Samples/UpdateSecretRotation.cs b/secretmanager/api/SecretManager.Samples/UpdateSecretRotation.cs new file mode 100644 index 00000000000..e43ca3bb83a --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/UpdateSecretRotation.cs @@ -0,0 +1,68 @@ +/* + * 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 + * + * 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 secretmanager_update_secret_rotation] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using Google.Protobuf.WellKnownTypes; +using System; + +public class UpdateSecretRotationSample +{ + public Secret UpdateSecretRotation(string projectId = "my-project", string secretId = "my-secret-with-rotation") + { + int newRotationPeriodHours = 48; + + // Create the client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the resource name of the secret. + SecretName secretName = new SecretName(projectId, secretId); + + // Convert rotation period to protobuf Duration + Duration rotationPeriod = new Duration + { + Seconds = newRotationPeriodHours * 3600 // Convert hours to seconds + }; + + // Create the update mask + FieldMask updateMask = new FieldMask { Paths = { "rotation.rotation_period" } }; + + // Build the secret with updated rotation period + Secret secretToUpdate = new Secret + { + SecretName = secretName, + Rotation = new Rotation + { + RotationPeriod = rotationPeriod + } + }; + + // Call the API. + Secret updatedSecret = client.UpdateSecret(new UpdateSecretRequest + { + Secret = secretToUpdate, + UpdateMask = updateMask + }); + + double rotationHours = updatedSecret.Rotation.RotationPeriod.Seconds / 3600.0; + Console.WriteLine($"Updated secret {updatedSecret.SecretName} rotation period to {rotationHours} hours"); + + return updatedSecret; + } +} +// [END secretmanager_update_secret_rotation] diff --git a/secretmanager/api/SecretManager.Samples/createRegionalSecretWithCmek.cs b/secretmanager/api/SecretManager.Samples/createRegionalSecretWithCmek.cs new file mode 100644 index 00000000000..5be2e2541d4 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/createRegionalSecretWithCmek.cs @@ -0,0 +1,57 @@ +/* + * 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 + * + * 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 secretmanager_create_regional_secret_with_cmek] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using System; + +public class CreateRegionalSecretWithCmekSample +{ + public Secret CreateRegionalSecretWithCmek( + string projectId = "my-project", + string locationId = "us-central1", + string secretId = "my-secret", + string kmsKeyName = "projects/my-project/locations/us-central1/keyRings/my-keyring/cryptoKeys/my-key") + { + // Create the Regional Secret Manager Client. + SecretManagerServiceClient client = new SecretManagerServiceClientBuilder + { + Endpoint = $"secretmanager.{locationId}.rep.googleapis.com" + }.Build(); + + // Build the parent resource name. + LocationName location = new LocationName(projectId, locationId); + + // Build the secret with CMEK. + Secret secret = new Secret + { + CustomerManagedEncryption = new CustomerManagedEncryption + { + KmsKeyName = kmsKeyName + } + }; + + // Call the API. + Secret createdSecret = client.CreateSecret(location, secretId, secret); + + // Print information about the created secret. + Console.WriteLine($"Created secret {createdSecret.Name} with CMEK key {kmsKeyName}"); + return createdSecret; + } +} +// [END secretmanager_create_regional_secret_with_cmek] diff --git a/secretmanager/api/SecretManager.Samples/createSecretWithCmek.cs b/secretmanager/api/SecretManager.Samples/createSecretWithCmek.cs new file mode 100644 index 00000000000..882e7687f99 --- /dev/null +++ b/secretmanager/api/SecretManager.Samples/createSecretWithCmek.cs @@ -0,0 +1,59 @@ +/* + * 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 + * + * 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 secretmanager_create_secret_with_cmek] + +using Google.Api.Gax.ResourceNames; +using Google.Cloud.SecretManager.V1; +using System; + +public class CreateSecretWithCmekSample +{ + public Secret CreateSecretWithCmek( + string projectId = "my-project", + string secretId = "my-secret", + string kmsKeyName = "projects/my-project/locations/global/keyRings/my-keyring/cryptoKeys/my-key") + { + // Create the client. + SecretManagerServiceClient client = SecretManagerServiceClient.Create(); + + // Build the parent resource name. + ProjectName projectName = new ProjectName(projectId); + + // Build the secret with automatic replication and CMEK. + Secret secret = new Secret + { + Replication = new Replication + { + Automatic = new Replication.Types.Automatic + { + CustomerManagedEncryption = new CustomerManagedEncryption + { + KmsKeyName = kmsKeyName + } + } + } + }; + + // Call the API. + Secret createdSecret = client.CreateSecret(projectName, secretId, secret); + + // Print information about the created secret. + Console.WriteLine($"Created secret {createdSecret.Name} with CMEK key {kmsKeyName}"); + return createdSecret; + } +} +// [END secretmanager_create_secret_with_cmek]