csharp icon indicating copy to clipboard operation
csharp copied to clipboard

AoT version with AKS `kubelogin` throws exception on creating configuration

Open dn-ark opened this issue 1 year ago • 6 comments

Describe the bug Using KubernetesClient.Aot throws an exception when trying to create a configuration via KubernetesClientConfiguration.BuildConfigFromConfigFile() that utilizes AKS kubelogin.

Exception is

k8s.Exceptions.KubeConfigException: 'external exec failed due to uncaught exception: System.ArgumentNullException: Value cannot be null. (Parameter 'jsonTypeInfo')
   at System.Text.Json.ThrowHelper.ThrowArgumentNullException(String parameterName)
   at System.Text.Json.JsonSerializer.Deserialize(String json, JsonTypeInfo jsonTypeInfo)
   at k8s.KubernetesJson.Deserialize[TValue](String json, JsonSerializerOptions jsonSerializerOptions)
   at k8s.KubernetesClientConfiguration.ExecuteExternalCommand(ExternalExecution config)'

Kubernetes C# SDK Client Version 15.0.1

Server Kubernetes Version 1.30.6

Dotnet Runtime Version .NET 9

To Reproduce

  1. Use kubelogin example as a reference
  2. First, confirm that regular KubernetesClient version 15.0.1 works correct when calling KubernetesClientConfiguration.BuildConfigFromConfigFile()
  3. Now change the package to KubernetesClient.Aot version 15.0.1 and try again - get an exception

Expected behavior Configuration should be created successfully.

KubeConfig Please refer to the linked sample but here's relevant users section from my config specifically:

users:
- name: clusterUser_<name>
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - get-token
      - --environment
      - AzurePublicCloud
      - --server-id
      - <server_id>
      - --client-id
      - <client_id>
      - --tenant-id
      - <tenant_id>
      - --login
      - devicecode
      command: kubelogin
      env: null
      installHint: |2

        kubelogin is not installed which is required to connect to AAD enabled cluster.

        To learn more, please go to https://aka.ms/aks/kubelogin
      interactiveMode: IfAvailable
      provideClusterInfo: false

Where do you run your app with Kubernetes SDK:

  • OS: Windows 11 Pro
  • Environment: Launching project with debug in Visual Studio

Additional context

dn-ark avatar Dec 19 '24 20:12 dn-ark

I guess it could be related to this one as well: https://github.com/kubernetes-client/csharp/issues/1598

dn-ark avatar Dec 19 '24 20:12 dn-ark

yup this is something dynamic, so not fully supported in aot

tg123 avatar Dec 19 '24 21:12 tg123

This should be fixable with a PR by setting the jsonTypeInfo on https://github.com/kubernetes-client/csharp/blob/61e6b13fd7828eb3d76b249b259b3444b0462564/src/KubernetesClient.Aot/KubernetesClientConfiguration.ConfigFile.cs#L515

[JsonSerializable(typeof(ExecCredentialResponse))]
internal partial class ExecCredentialResponseContext : JsonSerializerContext
{
}

IvanJosipovic avatar Dec 19 '24 22:12 IvanJosipovic

This should be fixable with a PR by setting the jsonTypeInfo on

csharp/src/KubernetesClient.Aot/KubernetesClientConfiguration.ConfigFile.cs

Line 515 in 61e6b13

var responseObject = KubernetesJson.Deserialize<ExecCredentialResponse>(process.StandardOutput.ReadToEnd());

[JsonSerializable(typeof(ExecCredentialResponse))]
internal partial class ExecCredentialResponseContext : JsonSerializerContext
{
}

The code dynamically looks up the JsonTypeInfo required in the AOT version of the deserialize method:

        public static TValue Deserialize<TValue>(string json, JsonSerializerOptions jsonSerializerOptions = null)
        {
            var info = SourceGenerationContext.Default.GetTypeInfo(typeof(TValue));
            return (TValue)JsonSerializer.Deserialize(json, info);
        }

#1616 should fix it, but I have not yet had a chance to test to verify that it fixes the exact problem that led me to this issue, nor have I had a chance to set up a test environment to run the unit tests. There is also the matter of how the project has multiple source generators operating on the same classes and while this is apparently working here, this is generally not supported, so I may be missing some nuances.

More generally, the JsonTypeInfo should probably be used for both the .Aot and non-.Aot versions of the client library (where possible, of course, and in such a way that the non-.Aot version can fall back to dynamic serialization code). Using the source generated JSON serializer that way would result in build-time errors instead of runtime errors whenever someone gets around to calling an impacted method. Such an approach would also provide a way to use CRDs with the .Aot version (and provide same the build vs runtime benefits). This does mean finding some way to do so for runtimes that support it, without making a mess of the templates/generated code for runtimes that do not.

What are the benefits of a user-configurable JsonSerializerOptions other than for interoperability with a (hopefully hypothetical) variant of Kubernetes that uses nearly the same API, but with incompatible JSON formatting? Many libraries and much sample code make JSON serialization configurable, but in this case a specific API with specific requirements is being targeted.

By similar arguments, regular expressions should probably be source generated as well. Beyond build-time error detection and reduced startup costs, this would also benefit performance on the .Aot version since the native runtime cannot do dynamically compilation.

In case anyone else is running into problems generating .sln files, it appears to be broken with version 12.0.3 of Microsoft.VisualStudio.SlnGen . Updating to 12.0.10 got it working for me.

TL;DR: source generation should be used where practical for both the .Aot and non-.Aot versions of the library.

henricj avatar Feb 17 '25 17:02 henricj

The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue as fresh with /remove-lifecycle stale
  • Close this issue with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

k8s-triage-robot avatar May 18 '25 18:05 k8s-triage-robot

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue as fresh with /remove-lifecycle rotten
  • Close this issue with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle rotten

k8s-triage-robot avatar Jun 17 '25 18:06 k8s-triage-robot

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Reopen this issue with /reopen
  • Mark this issue as fresh with /remove-lifecycle rotten
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/close not-planned

k8s-triage-robot avatar Jul 17 '25 19:07 k8s-triage-robot

@k8s-triage-robot: Closing this issue, marking it as "Not Planned".

In response to this:

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Reopen this issue with /reopen
  • Mark this issue as fresh with /remove-lifecycle rotten
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/close not-planned

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

k8s-ci-robot avatar Jul 17 '25 19:07 k8s-ci-robot

/reopen This issue still exists

k7o avatar Aug 02 '25 10:08 k7o