From 3fd47e5644f273fa66cf15530ea12bdfa7e81a76 Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Mon, 23 Nov 2020 02:59:34 -0800 Subject: [PATCH] Add an initial generic client. (#525) --- examples/generic/Generic.cs | 25 +++++++ examples/generic/generic.csproj | 13 ++++ src/KubernetesClient/GenericClient.cs | 96 +++++++++++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 examples/generic/Generic.cs create mode 100644 examples/generic/generic.csproj create mode 100644 src/KubernetesClient/GenericClient.cs diff --git a/examples/generic/Generic.cs b/examples/generic/Generic.cs new file mode 100644 index 0000000..af11992 --- /dev/null +++ b/examples/generic/Generic.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using k8s; +using k8s.Models; + +namespace exec +{ + internal class Generic + { + private static async Task Main(string[] args) + { + var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(); + var generic = new GenericClient(config, "", "v1", "nodes"); + var node = await generic.ReadAsync("kube0").ConfigureAwait(false); + Console.WriteLine(node.Metadata.Name); + + var genericPods = new GenericClient(config, "", "v1", "pods"); + var pods = await genericPods.ListNamespacedAsync("default").ConfigureAwait(false); + foreach (var pod in pods.Items) + { + Console.WriteLine(pod.Metadata.Name); + } + } + } +} diff --git a/examples/generic/generic.csproj b/examples/generic/generic.csproj new file mode 100644 index 0000000..651bf99 --- /dev/null +++ b/examples/generic/generic.csproj @@ -0,0 +1,13 @@ + + + + + + + + Exe + net5 + 7.1 + + + diff --git a/src/KubernetesClient/GenericClient.cs b/src/KubernetesClient/GenericClient.cs new file mode 100644 index 0000000..ebad396 --- /dev/null +++ b/src/KubernetesClient/GenericClient.cs @@ -0,0 +1,96 @@ +using Microsoft.Rest.Serialization; +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + + +namespace k8s +{ + public class GenericClient : IDisposable + { + internal class TweakApiHandler : DelegatingHandler + { + protected override Task SendAsync(HttpRequestMessage msg, CancellationToken cancel) + { + msg.RequestUri = new Uri(msg.RequestUri, msg.RequestUri.AbsolutePath.Replace("/apis//", "/api/")); + return base.SendAsync(msg, cancel); + } + } + + private IKubernetes kubernetes; + private string group; + private string version; + private string plural; + + + public GenericClient(KubernetesClientConfiguration config, string group, string version, string plural) + { + this.group = group; + this.version = version; + this.plural = plural; + + if (string.IsNullOrEmpty(group)) + { + this.kubernetes = new Kubernetes(config, new DelegatingHandler[] { new TweakApiHandler() }); + } + else + { + this.kubernetes = new Kubernetes(config); + } + } + + public async Task ListAsync(CancellationToken cancel = default(CancellationToken)) + where T : IKubernetesObject + { + var resp = await this.kubernetes.ListClusterCustomObjectWithHttpMessagesAsync(this.group, this.version, this.plural, cancellationToken: cancel).ConfigureAwait(false); + return SafeJsonConvert.DeserializeObject(resp.Body.ToString()); + } + + public async Task ListNamespacedAsync(string ns, CancellationToken cancel = default(CancellationToken)) + where T : IKubernetesObject + { + var resp = await this.kubernetes.ListNamespacedCustomObjectWithHttpMessagesAsync(this.group, this.version, ns, this.plural, cancellationToken: cancel).ConfigureAwait(false); + return SafeJsonConvert.DeserializeObject(resp.Body.ToString()); + } + + public async Task ReadNamespacedAsync(string ns, string name, CancellationToken cancel = default(CancellationToken)) + where T : IKubernetesObject + { + var resp = await this.kubernetes.GetNamespacedCustomObjectWithHttpMessagesAsync(this.group, this.version, ns, this.plural, name, cancellationToken: cancel).ConfigureAwait(false); + return SafeJsonConvert.DeserializeObject(resp.Body.ToString()); + } + + public async Task ReadAsync(string name, CancellationToken cancel = default(CancellationToken)) + where T : IKubernetesObject + { + var resp = await this.kubernetes.GetClusterCustomObjectWithHttpMessagesAsync(this.group, this.version, this.plural, name, cancellationToken: cancel).ConfigureAwait(false); + return SafeJsonConvert.DeserializeObject(resp.Body.ToString()); + } + + public async Task DeleteAsync(string name, CancellationToken cancel = default(CancellationToken)) + where T : IKubernetesObject + { + var resp = await this.kubernetes.DeleteClusterCustomObjectWithHttpMessagesAsync(this.group, this.version, this.plural, name, cancellationToken: cancel).ConfigureAwait(false); + return SafeJsonConvert.DeserializeObject(resp.Body.ToString()); + } + + public async Task DeleteNamespacedAsync(string ns, string name, CancellationToken cancel = default(CancellationToken)) + where T : IKubernetesObject + { + var resp = await this.kubernetes.DeleteNamespacedCustomObjectWithHttpMessagesAsync(this.group, this.version, ns, this.plural, name, cancellationToken: cancel).ConfigureAwait(false); + return SafeJsonConvert.DeserializeObject(resp.Body.ToString()); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + this.kubernetes.Dispose(); + } + } +}