Skip to content

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

Closed
@slacki123

Description

@slacki123

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions