azure-libraries-for-net: [BUG] Key Vault update is failing with Fluent API because of api version 2021-06-01-preview requires publicNetworkAccess property

Description When you get a key vault resource (using client.GenericResources.GetById(resourceId);) and try to update it, it throws the following error. The 'PublicNetworkAccess' property can not be empty. Please specify an authorized value.

After fiddling around in network traces, I managed to figure out the exact reason why is it failing. The culprit is the new api-version=2021-06-01-preview. The new API version requires the property publicNetworkAccess if you want to update the resource. However, while creating the resource using Azure Portal does not set this property at all.

Steps to reproduce

With Azure Resource Manager Fluent API -

  1. Create a new Key Vault resource in Azure Portal.
  2. Get the Key Vault Resource IGenericResource resource = client.GenericResources.GetById(resourceId); - Notice the API Version (resource.ApiVersion) being returned by this method, it is set to 2021-06-01-preview. Also, notice the properties being retrieved. The property publicNetworkAccess is missing.

image

  1. Now update the Key Vault (e.g. in my case, I updated with a set of custom tags).
 var result = await resource.Update().WithApiVersion(resource.ApiVersion).WithProperties(resource.Properties).WithTags(resourceNewTags).ApplyAsync();

  1. This will throw an exception - The 'PublicNetworkAccess' property can not be empty. Please specify an authorized value.

Exception or Stack Trace

at Microsoft.Azure.Management.ResourceManager.Fluent.ResourcesOperations. 
<BeginCreateOrUpdateWithHttpMessagesAsync>d__22.MoveNext()
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
  at Microsoft.Azure.Management.ResourceManager.Fluent.ResourcesOperations. 
<CreateOrUpdateWithHttpMessagesAsync>d__11.MoveNext()
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
  at Microsoft.Azure.Management.ResourceManager.Fluent.ResourcesOperationsExtensions. 
<CreateOrUpdateAsync>d__6.MoveNext()
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
  at Microsoft.Azure.Management.ResourceManager.Fluent.GenericResourceImpl.<CreateResourceAsync>d__18.MoveNext()
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
  at Microsoft.Azure.Management.ResourceManager.Fluent.Core.ResourceActions.Creatable`4.<Microsoft-Azure-Management- 
ResourceManager-Fluent-Core-ResourceActions-IResourceCreator<IResourceT>-CreateResourceAsync>d__15.MoveNext()
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
  at Microsoft.Azure.Management.ResourceManager.Fluent.Core.DAG.CreatorTaskItem`1.<ExecuteAsync>d__6.MoveNext()
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
  at Microsoft.Azure.Management.ResourceManager.Fluent.Core.DAG.TaskGroupBase`1. 
<ExecuteNodeTaskAsync>d__14.MoveNext()
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
  at Microsoft.Azure.Management.ResourceManager.Fluent.Core.ResourceActions.CreatableUpdatable`5.<ApplyAsync>d__3.MoveNext()
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
  at SensitiveInformation.ClassName.<AddOrUpdateResourceTags>d__6.MoveNext() in C:\hidden_sensitive_information\class_name.cs:line 204
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
  at SensitiveInformation.ClassName.<Method_Name>d__14.MoveNext() in C:\hidden_sensitive_information\class_name.cs:line 201

Code Snippet

await resource.Update()
.WithApiVersion(resource.ApiVersion)
.WithProperties(resource.Properties)
.WithTags(resourceNewTags).ApplyAsync();

Expected behavior The method IGenericResource resource = client.GenericResources.GetById(resourceId); should return property publicNetworkAccess of an existing resource. Or make it an optional field (as the provisioning of key vault resource from the portal does not require that field at all)

Setup (please complete the following information): Library - Microsoft.Azure.Management.Fluent v 1.37.1 Rest API - api-version=2021-04-01-preview

Information Checklist

  • Bug Description Added
  • Repro Steps Added
  • Setup information Added

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 18 (12 by maintainers)

Most upvoted comments

1.38.0 released

I am making (a possible last big update) on SDK to have it support tagging API. https://github.com/Azure/azure-libraries-for-net/pull/1261

Though next release date is not decided yet.

            var ret = azure.GenericResources.Manager.Inner.Tags.UpdateAtScopeAsync(r.Id, new TagsPatchResource()
            {
                Operation = TagsPatchOperation.Replace,
                Properties = new TagsInner()
                {
                    TagsProperty = new Dictionary<string, string>()
                    {
                        { "tag", "value" }
                    }
                }
            }).Result;

@RandalliLama, @schaabs, @jlichwa Please help check on keyvault service. A PATCH to key vault which only update tags should not cause this kind of 400 BadRequest. Even ARM would do this to update resource tag.

Request: PATCH https://management.azure.com/subscriptions/###/resourceGroups/rg-weidxu1/providers/Microsoft.KeyVault/vaults/kvweidxu112321?api-version=2021-06-01-preview
  body: {
  "tags": {
    "a": "b"
  }
}

Response:
{
  "error": {
    "code": "BadRequest",
    "message": "The 'PublicNetworkAccess' property can not be empty. Please specify an authorized value."
  }
}