diff --git a/kubernetes-client.sln b/kubernetes-client.sln
index 58577c9..98edcf2 100644
--- a/kubernetes-client.sln
+++ b/kubernetes-client.sln
@@ -51,7 +51,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "yaml", "examples\yaml\yaml.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KubernetesClient.Models", "src\KubernetesClient.Models\KubernetesClient.Models.csproj", "{F066A4D8-2EF0-4C07-AC0D-BD325DE3FFA8}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KubernetesClient.Basic", "src\KubernetesClient.Basic\KubernetesClient.Basic.csproj", "{927995F5-05CC-4078-8805-8E6CC06914D8}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KubernetesClient.Basic", "src\KubernetesClient.Basic\KubernetesClient.Basic.csproj", "{927995F5-05CC-4078-8805-8E6CC06914D8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KubernetesClient.Classic", "src\KubernetesClient.Classic\KubernetesClient.Classic.csproj", "{80F19E8A-F097-4AA4-A68C-D417B96BBC68}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KubernetesClient.Classic.Tests", "tests\KubernetesClient.Classic.Tests\KubernetesClient.Classic.Tests.csproj", "{FD90C861-56C6-4536-B7F5-AC7779296384}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csrApproval", "examples\csrApproval\csrApproval.csproj", "{F626860C-F141-45B3-9DDD-88AD3932ACAF}"
EndProject
@@ -329,6 +333,30 @@ Global
{927995F5-05CC-4078-8805-8E6CC06914D8}.Release|x64.Build.0 = Release|Any CPU
{927995F5-05CC-4078-8805-8E6CC06914D8}.Release|x86.ActiveCfg = Release|Any CPU
{927995F5-05CC-4078-8805-8E6CC06914D8}.Release|x86.Build.0 = Release|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Debug|x64.Build.0 = Debug|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Debug|x86.Build.0 = Debug|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Release|Any CPU.Build.0 = Release|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Release|x64.ActiveCfg = Release|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Release|x64.Build.0 = Release|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Release|x86.ActiveCfg = Release|Any CPU
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68}.Release|x86.Build.0 = Release|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Debug|x64.Build.0 = Debug|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Debug|x86.Build.0 = Debug|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Release|x64.ActiveCfg = Release|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Release|x64.Build.0 = Release|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Release|x86.ActiveCfg = Release|Any CPU
+ {FD90C861-56C6-4536-B7F5-AC7779296384}.Release|x86.Build.0 = Release|Any CPU
{F626860C-F141-45B3-9DDD-88AD3932ACAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F626860C-F141-45B3-9DDD-88AD3932ACAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F626860C-F141-45B3-9DDD-88AD3932ACAF}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -368,6 +396,8 @@ Global
{17AB0AD8-6C90-42DD-880C-16B5AC4A373F} = {B70AFB57-57C9-46DC-84BE-11B7DDD34B40}
{F066A4D8-2EF0-4C07-AC0D-BD325DE3FFA8} = {3D1864AA-1FFC-4512-BB13-46055E410F73}
{927995F5-05CC-4078-8805-8E6CC06914D8} = {3D1864AA-1FFC-4512-BB13-46055E410F73}
+ {80F19E8A-F097-4AA4-A68C-D417B96BBC68} = {3D1864AA-1FFC-4512-BB13-46055E410F73}
+ {FD90C861-56C6-4536-B7F5-AC7779296384} = {8AF4A5C2-F0CE-47D5-A4C5-FE4AB83CA509}
{F626860C-F141-45B3-9DDD-88AD3932ACAF} = {B70AFB57-57C9-46DC-84BE-11B7DDD34B40}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
diff --git a/src/KubernetesClient.Classic/Global.cs b/src/KubernetesClient.Classic/Global.cs
new file mode 100644
index 0000000..f96593e
--- /dev/null
+++ b/src/KubernetesClient.Classic/Global.cs
@@ -0,0 +1,4 @@
+global using System;
+global using System.Collections.Generic;
+global using System.Linq;
+global using System.Text.Json;
diff --git a/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj b/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj
new file mode 100644
index 0000000..b4041cd
--- /dev/null
+++ b/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj
@@ -0,0 +1,43 @@
+
+
+
+ netstandard2.0;net48
+ k8s
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/KubernetesClient/Authentication/TokenFileAuth.cs b/src/KubernetesClient/Authentication/TokenFileAuth.cs
index 181f09b..1925b3c 100644
--- a/src/KubernetesClient/Authentication/TokenFileAuth.cs
+++ b/src/KubernetesClient/Authentication/TokenFileAuth.cs
@@ -17,13 +17,21 @@ namespace k8s.Authentication
TokenFile = tokenFile;
}
+#if NETSTANDARD2_1_OR_GREATER
public async Task GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
+#else
+ public Task GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
+#endif
{
if (TokenExpiresAt < DateTime.UtcNow)
{
+#if NETSTANDARD2_1_OR_GREATER
token = await File.ReadAllTextAsync(TokenFile, cancellationToken)
.ContinueWith(r => r.Result.Trim(), cancellationToken)
.ConfigureAwait(false);
+#else
+ token = File.ReadAllText(TokenFile).Trim();
+#endif
// in fact, the token has a expiry of 10 minutes and kubelet
// refreshes it at 8 minutes of its lifetime. setting the expiry
// of 1 minute makes sure the token is reloaded regularly so
@@ -32,8 +40,11 @@ namespace k8s.Authentication
// < 10-8-1 minute.
TokenExpiresAt = DateTime.UtcNow.AddMinutes(1);
}
-
+#if NETSTANDARD2_1_OR_GREATER
return new AuthenticationHeaderValue("Bearer", token);
+#else
+ return Task.FromResult(new AuthenticationHeaderValue("Bearer", token));
+#endif
}
}
}
diff --git a/src/KubernetesClient/Kubernetes.ConfigInit.cs b/src/KubernetesClient/Kubernetes.ConfigInit.cs
index e6a8bbf..fd11e40 100644
--- a/src/KubernetesClient/Kubernetes.ConfigInit.cs
+++ b/src/KubernetesClient/Kubernetes.ConfigInit.cs
@@ -23,7 +23,9 @@ namespace k8s
Initialize();
ValidateConfig(config);
CaCerts = config.SslCaCerts;
+#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER
SkipTlsVerify = config.SkipTlsVerify;
+#endif
CreateHttpClient(handlers, config);
InitializeFromConfig(config);
HttpClientTimeout = config.HttpClientTimeout;
@@ -100,9 +102,11 @@ namespace k8s
private X509Certificate2Collection CaCerts { get; }
+#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER
private X509Certificate2 ClientCert { get; }
private bool SkipTlsVerify { get; }
+#endif
// NOTE: this method replicates the logic that the base ServiceClient uses except that it doesn't insert the RetryDelegatingHandler
// and it does insert the WatcherDelegatingHandler. we don't want the RetryDelegatingHandler because it has a very broad definition
diff --git a/src/KubernetesClient/Kubernetes.cs b/src/KubernetesClient/Kubernetes.cs
index 506d7a4..e4a3f5b 100644
--- a/src/KubernetesClient/Kubernetes.cs
+++ b/src/KubernetesClient/Kubernetes.cs
@@ -71,7 +71,11 @@ namespace k8s
if (watch == true)
{
+#if NETSTANDARD2_0 || NET48
+ throw new KubernetesException("watch not supported");
+#else
httpResponse.Content = new LineSeparatedHttpContent(httpResponse.Content, cancellationToken);
+#endif
}
try
@@ -100,7 +104,9 @@ namespace k8s
var httpRequest = new HttpRequestMessage();
httpRequest.Method = new HttpMethod(method);
httpRequest.RequestUri = new Uri(BaseUri, relativeUri);
+#if NETSTANDARD2_1_OR_GREATER
httpRequest.Version = HttpVersion.Version20;
+#endif
// Set Headers
if (customHeaders != null)
{
diff --git a/src/nuget.proj b/src/nuget.proj
index 236467f..fa0a58d 100644
--- a/src/nuget.proj
+++ b/src/nuget.proj
@@ -3,5 +3,6 @@
+
diff --git a/tests/KubernetesClient.Classic.Tests/KubernetesClient.Classic.Tests.csproj b/tests/KubernetesClient.Classic.Tests/KubernetesClient.Classic.Tests.csproj
new file mode 100644
index 0000000..1e9f3a4
--- /dev/null
+++ b/tests/KubernetesClient.Classic.Tests/KubernetesClient.Classic.Tests.csproj
@@ -0,0 +1,42 @@
+
+
+ false
+ k8s.Tests
+ net6
+ net6;net48
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/KubernetesClient.Classic.Tests/SimpleTests.cs b/tests/KubernetesClient.Classic.Tests/SimpleTests.cs
new file mode 100644
index 0000000..0520299
--- /dev/null
+++ b/tests/KubernetesClient.Classic.Tests/SimpleTests.cs
@@ -0,0 +1,81 @@
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+using Xunit;
+using k8s.Models;
+
+namespace k8s.tests;
+
+public class BasicTests
+{
+ // TODO: fail to setup asp.net core 6 on net48
+ private class DummyHttpServer : System.IDisposable
+ {
+ private TcpListener server;
+ private readonly Task loop;
+ private volatile bool running = false;
+
+ public string Addr => $"http://{server.LocalEndpoint}";
+
+ public DummyHttpServer(object obj)
+ {
+ server = new TcpListener(IPAddress.Parse("127.0.0.1"), 0);
+ server.Start();
+ running = true;
+ loop = Task.Run(async () =>
+ {
+ while (running)
+ {
+ var result = KubernetesJson.Serialize(obj);
+
+ var client = await server.AcceptTcpClientAsync().ConfigureAwait(false);
+ var stream = client.GetStream();
+ stream.Read(new byte[1024], 0, 1024); // TODO ensure full header
+
+ var writer = new StreamWriter(stream);
+ await writer.WriteLineAsync("HTTP/1.0 200 OK").ConfigureAwait(false);
+ await writer.WriteLineAsync("Content-Length: " + result.Length).ConfigureAwait(false);
+ await writer.WriteLineAsync("Content-Type: application/json").ConfigureAwait(false);
+ await writer.WriteLineAsync().ConfigureAwait(false);
+ await writer.WriteLineAsync(result).ConfigureAwait(false);
+
+ await writer.FlushAsync().ConfigureAwait(false);
+ client.Close();
+ }
+ });
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ running = false;
+ server.Stop();
+ loop.Wait();
+ loop.Dispose();
+ }
+ catch
+ {
+ // ignore
+ }
+ }
+ }
+
+ [Fact]
+ public async Task QueryPods()
+ {
+ using var server = new DummyHttpServer(new V1Pod()
+ {
+ Metadata = new V1ObjectMeta()
+ {
+ Name = "pod0",
+ },
+ });
+ var client = new Kubernetes(new KubernetesClientConfiguration { Host = server.Addr });
+
+ var pod = await client.ReadNamespacedPodAsync("pod", "default").ConfigureAwait(false);
+
+ Assert.Equal("pod0", pod.Metadata.Name);
+ }
+}
diff --git a/tests/KubernetesClient.Tests/KubernetesClient.Tests.csproj b/tests/KubernetesClient.Tests/KubernetesClient.Tests.csproj
index bbd49e2..943de42 100755
--- a/tests/KubernetesClient.Tests/KubernetesClient.Tests.csproj
+++ b/tests/KubernetesClient.Tests/KubernetesClient.Tests.csproj
@@ -1,8 +1,6 @@
-
+
false
- 8
- true
k8s.Tests
netcoreapp3.1;net5.0;net6.0