Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KubernetesJson fails to deserialize custom resource into ResourceQuantity if values are numbers #1396

Closed
slacki123 opened this issue Sep 7, 2023 · 0 comments · Fixed by #1397

Comments

@slacki123
Copy link

Describe the bug
I have noticed a bug with KubernetesJson that if we create a CustomResourceDefinition that takes a ResourceQuantity schema where for example resource 'cpu' value is a number, deserialization fails. It only accepts strings for KubernetesJson deserializers.

Custom resource example that works and cpu properly deserializes into a ResourceQuantity object in c#:

{
  "resources": {
    "limits": {
      "cpu": "1",
      "memory": "1Mi"
    }
  }
}

Custom resource example that fails because cpu is a "number" and not a string:

{
 "resources": {
   "limits": {
     "cpu": 1,
     "memory": "1Mi"
   }
 }
}

This fails with a long error error such as

System.Text.Json.JsonException: The JSON value could not be converted to k8s.Models.ResourceQuantity. 
Path: $.object.spec.mycustomresource.spec.template.spec.containers[0].resources.limits.cpu | LineNumber: 0 | BytePositionInLine: 1633.  ---> System.InvalidOperationException: Cannot get the value of a token type 'Number' as a string.    
  at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_ExpectedString(JsonTokenType tokenType)   
  at System.Text.Json.Utf8JsonReader.GetString()    
  at k8s.Models.ResourceQuantityJsonConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options) 

When using KubernetesYaml however, this works as expected and the values deserialize to the custom object containing a ResourceQuantity type as expected, regardless of whether the cpu value is a string or a number.

My assumption that the root issue here lies with KubernetesJson that does not handle ResourceQuantity object deserialization.
KubernetesYaml handles it properly on the other hand.

Although the above is mainly a guess. Does any one know what the issue here might be exactly?

Kubernetes C# SDK Client Version
10.0.31

Server Kubernetes Version
1.24.16

Dotnet Runtime Version
net6

To Reproduce
create a json that can deserialize into a ResourceQuantity, for example:

string jsonString = @"{""cpu"": ""1""}";
// this will deserialize fine
var test = KubernetesJson.Deserialize<Dictionary<string, ResourceQuantity>>(jsonString);

The following will fail since cpu is now a number:

string jsonString = @"{""cpu"": 1}";
// this will fail because cpu value is a number
var test = KubernetesJson.Deserialize<Dictionary<string, ResourceQuantity>>(jsonString);

Should result in the following error

ystem.Text.Json.JsonException: The JSON value could not be converted to k8s.Models.ResourceQuantity. Path: $.cpu | LineNumber: 0 | BytePositionInLine: 9.
---> System.InvalidOperationException: Cannot get the value of a token type 'Number' as a string.
  at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_ExpectedString(JsonTokenType tokenType)
  at System.Text.Json.Utf8JsonReader.GetString()
  at k8s.Models.ResourceQuantityJsonConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
  at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
  at System.Text.Json.Serialization.JsonDictionaryConverter`3.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TDictionary& value)
  at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
  at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)

When running KubernetesYaml, it deserializes properly

string jsonString = @"{""cpu"": 1}";
var test = KubernetesYaml.Deserialize<Dictionary<string, ResourceQuantity>>(jsonString); // no error

Expected behavior
KubernetesJson should deserialize a string with a ResourceQuantity properly regardless of whether it is a string or an int

Where do you run your app with Kubernetes SDK (please complete the following information):

  • OS: MacOs
  • Environment: LocalMachine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant