Closed r4hulp closed 2 years ago
Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @RandalliLama, @schaabs, @jlichwa.
Author: | r4hulp |
---|---|
Assignees: | - |
Labels: | `KeyVault`, `Service Attention` |
Milestone: | - |
Loop in service on question of why PublicNetworkAccess
now becomes a required property (while it is not required in either VaultProperties
nor VaultPatchProperties
in swagger https://github.com/Azure/azure-rest-api-specs/blob/main/specification/keyvault/resource-manager/Microsoft.KeyVault/preview/2021-06-01-preview/keyvault.json#L1312-L1321).
Generally it is suggested to fix the api-version
when interacting with GenericResource
. Though in theory service is backward-compatible, but in many case it does not.
@weidongxu-microsoft - not sure if these comments are directed towards me or your team.
@r4hulp It is about the usage of the GenericResource
.
BTW, new .NET SDK will get previewed at https://azure.github.io/azure-sdk/releases/latest/mgmt/dotnet.html, about the end of August.
I don't understand one thing though, why is the property publicNetworkAccess
not being set by default while creating the Key Vault resource if it is supposed to be a required field?
@r4hulp If you create the vault on Portal, and in last step click "download template", you can see it is created via "2018-02-14" api-version, which does not contain this publicNetworkAccess
property/feature in the first place.
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"sku": {
"type": "string"
},
"accessPolicies": {
"type": "array"
},
"tenant": {
"type": "string"
},
"enabledForDeployment": {
"type": "bool"
},
"enabledForTemplateDeployment": {
"type": "bool"
},
"enabledForDiskEncryption": {
"type": "bool"
},
"enableRbacAuthorization": {
"type": "bool"
},
"enableSoftDelete": {
"type": "bool"
},
"softDeleteRetentionInDays": {
"type": "int"
},
"networkAcls": {
"type": "object"
}
},
"variables": {},
"resources": [
{
"apiVersion": "2018-02-14",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"type": "Microsoft.KeyVault/vaults",
"properties": {
"enabledForDeployment": "[parameters('enabledForDeployment')]",
"enabledForTemplateDeployment": "[parameters('enabledForTemplateDeployment')]",
"enabledForDiskEncryption": "[parameters('enabledForDiskEncryption')]",
"enableRbacAuthorization": "[parameters('enableRbacAuthorization')]",
"accessPolicies": "[parameters('accessPolicies')]",
"tenantId": "[parameters('tenant')]",
"sku": {
"name": "[parameters('sku')]",
"family": "A"
},
"enableSoftDelete": "[parameters('enableSoftDelete')]",
"softDeleteRetentionInDays": "[parameters('softDeleteRetentionInDays')]",
"networkAcls": "[parameters('networkAcls')]"
},
"tags": {},
"dependsOn": []
}
],
"outputs": {}
}
@r4hulp If you create the vault on Portal, and in last step click "download template", you can see it is created via "2018-02-14" api-version, which does not contain this
publicNetworkAccess
property/feature in the first place.{ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "name": { "type": "string" }, "location": { "type": "string" }, "sku": { "type": "string" }, "accessPolicies": { "type": "array" }, "tenant": { "type": "string" }, "enabledForDeployment": { "type": "bool" }, "enabledForTemplateDeployment": { "type": "bool" }, "enabledForDiskEncryption": { "type": "bool" }, "enableRbacAuthorization": { "type": "bool" }, "enableSoftDelete": { "type": "bool" }, "softDeleteRetentionInDays": { "type": "int" }, "networkAcls": { "type": "object" } }, "variables": {}, "resources": [ { "apiVersion": "2018-02-14", "name": "[parameters('name')]", "location": "[parameters('location')]", "type": "Microsoft.KeyVault/vaults", "properties": { "enabledForDeployment": "[parameters('enabledForDeployment')]", "enabledForTemplateDeployment": "[parameters('enabledForTemplateDeployment')]", "enabledForDiskEncryption": "[parameters('enabledForDiskEncryption')]", "enableRbacAuthorization": "[parameters('enableRbacAuthorization')]", "accessPolicies": "[parameters('accessPolicies')]", "tenantId": "[parameters('tenant')]", "sku": { "name": "[parameters('sku')]", "family": "A" }, "enableSoftDelete": "[parameters('enableSoftDelete')]", "softDeleteRetentionInDays": "[parameters('softDeleteRetentionInDays')]", "networkAcls": "[parameters('networkAcls')]" }, "tags": {}, "dependsOn": [] } ], "outputs": {} }
Understood, but then apiVersion
in the code below should be consistent with the API version the resource was created.
IGenericResource resource = client.GenericResources.GetById(resourceId);
string apiVersion = resource.ApiVersion
I created a new Key Vault in Portal, and the template in Export Template section has API Version 2021-04-01-preview
(see the image below) -
However if I query the exact resource using Azure Resource Manager i.e. client.GenericResources.GetById(resourceId);
, it has API Version 2021-06-01-preview
. This is inconsistent in my opinion.
Does GetById(resourceId)
always returns latest and greatest ApiVersion? If yes, is there any way to know which API Version the resource was created with?
@r4hulp This is the reason I was suggesting to provide the apiVersion
to GetById
in the first place (or provide it to Update
later).
Without user providing the api-verison
, SDK would had to go find one. Generally it has only one choice: take the latest version, which is "2021-06-01-preview" for vault. (Some later version of API would have another option to take a default version, which is "2019-09-01" for vault).
If you are using the GenericResource
API, generally it is up to you to provide the api-version
to SDK.
If you know it is vault, you can go with Vault
API, which do know the api-version
.
@r4hulp This is the reason I was suggesting to provide the
apiVersion
toGetById
in the first place (or provide it toUpdate
later).Without user providing the
api-verison
, SDK would had to go find one. Generally it has only one choice: take the latest version, which is "2021-06-01-preview" for vault. (Some later version of API would have another option to take a default version, which is "2019-09-01" for vault).If you are using the
GenericResource
API, generally it is up to you to provide theapi-version
to SDK.If you know it is vault, you can go with
Vault
API, which do know theapi-version
.
That's a problem, we don't know if it is a vault, we loop through all the available resources in the resource group and apply one custom tag to them dynamically. It is hard to identify and pass in the api-version
for each and every resource. If there was a way to get the apiVersion
used while provisioning the resource, we could use that value itself to update to avoid such breaking scenarios. I can't find a way to get apiVersion
used to create the resource in GenericResource
API.
What would you suggest in this case?
@r4hulp When the new SDK gets out, you should be able to do the tagging on the dedicated APIs. https://docs.microsoft.com/en-us/rest/api/resources/tags
The current SDK is pretty old and does not include the tagging API.
If you still need to stick with current SDK for some time, you can try this (which do a PATCH):
var ret = azure.GenericResources.Manager.Inner.Resources.UpdateByIdAsync(resource.Id, resource.ApiVersion, new GenericResourceInner()
{
Tags = new Dictionary<String, String> {
{ "a", "b" }
}
}).Result;
If you still need to stick with the current SDK for some time, you can try this (which do a PATCH):
var ret = azure.GenericResources.Manager.Inner.Resources.UpdateByIdAsync(resource.Id, resource.ApiVersion, new GenericResourceInner() { Tags = new Dictionary<String, String> { { "a", "b" } } }).Result;
The patch method also expects the PublicNetworkAccess
property (which is weird in my opinion).
{"error":{"code":"BadRequest","message":"The 'PublicNetworkAccess' property can not be empty. Please specify an authorized value."}}
Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @RandalliLama, @schaabs, @jlichwa.
Author: | r4hulp |
---|---|
Assignees: | - |
Labels: | `KeyVault`, `Service Attention`, `Mgmt` |
Milestone: | - |
@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."
}
}
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;
Thanks. For the time being, we have written a fallback code to connect to Tags API instead of using SDK. Will be awaiting the release
1.38.0 released
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 propertypublicNetworkAccess
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 -
IGenericResource resource = client.GenericResources.GetById(resourceId);
- Notice the API Version (resource.ApiVersion
) being returned by this method, it is set to2021-06-01-preview
. Also, notice the properties being retrieved. The propertypublicNetworkAccess
is missing.at Microsoft.Azure.Management.ResourceManager.Fluent.ResourcesOperations.