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

AoT version with AKS kubelogin throws exception on creating configuration #1602

Open
dn-ark opened this issue Dec 19, 2024 · 4 comments · May be fixed by #1616
Open

AoT version with AKS kubelogin throws exception on creating configuration #1602

dn-ark opened this issue Dec 19, 2024 · 4 comments · May be fixed by #1616

Comments

@dn-ark
Copy link

dn-ark commented Dec 19, 2024

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
Copy link
Author

dn-ark commented Dec 19, 2024

I guess it could be related to this one as well: #1598

@tg123
Copy link
Member

tg123 commented Dec 19, 2024

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

@IvanJosipovic
Copy link
Contributor

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

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

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

henricj added a commit to henricj/csharp that referenced this issue Feb 17, 2025
@henricj henricj linked a pull request Feb 17, 2025 that will close this issue
@henricj
Copy link

henricj commented Feb 17, 2025

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(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.

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.

4 participants