add generic create (#744)

* add generic create

* flaky test on test env
This commit is contained in:
Boshi Lian
2021-11-12 12:06:28 -08:00
committed by GitHub
parent 4ff1ea49b8
commit f515fb4d76
4 changed files with 127 additions and 18 deletions

View File

@@ -10,11 +10,12 @@ namespace exec
private static async Task Main(string[] args)
{
var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
var generic = new GenericClient(config, "", "v1", "nodes");
IKubernetes client = new Kubernetes(config);
var generic = new GenericClient(client, "", "v1", "nodes");
var node = await generic.ReadAsync<V1Node>("kube0").ConfigureAwait(false);
Console.WriteLine(node.Metadata.Name);
var genericPods = new GenericClient(config, "", "v1", "pods");
var genericPods = new GenericClient(client, "", "v1", "pods");
var pods = await genericPods.ListNamespacedAsync<V1PodList>("default").ConfigureAwait(false);
foreach (var pod in pods.Items)
{

View File

@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29230.47
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B70AFB57-57C9-46DC-84BE-11B7DDD34B40}"
EndProject
@@ -43,7 +43,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "customResource", "examples\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KubernetesGenerator", "gen\KubernetesGenerator\KubernetesGenerator.csproj", "{79BA7C4A-98AA-467E-80D4-0E4F03EE6DDE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenericKubernetesApi", "examples\GenericKubernetesApi\GenericKubernetesApi.csproj", "{F81AE4C4-E044-4225-BD76-385A0DE621FD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GenericKubernetesApi", "examples\GenericKubernetesApi\GenericKubernetesApi.csproj", "{F81AE4C4-E044-4225-BD76-385A0DE621FD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "generic", "examples\generic\generic.csproj", "{F06D4C3A-7825-43A8-832B-6BDE3D355486}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -259,6 +261,18 @@ Global
{F81AE4C4-E044-4225-BD76-385A0DE621FD}.Release|x64.Build.0 = Release|Any CPU
{F81AE4C4-E044-4225-BD76-385A0DE621FD}.Release|x86.ActiveCfg = Release|Any CPU
{F81AE4C4-E044-4225-BD76-385A0DE621FD}.Release|x86.Build.0 = Release|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Debug|x64.ActiveCfg = Debug|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Debug|x64.Build.0 = Debug|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Debug|x86.ActiveCfg = Debug|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Debug|x86.Build.0 = Debug|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Release|Any CPU.Build.0 = Release|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Release|x64.ActiveCfg = Release|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Release|x64.Build.0 = Release|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Release|x86.ActiveCfg = Release|Any CPU
{F06D4C3A-7825-43A8-832B-6BDE3D355486}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -281,6 +295,7 @@ Global
{95672061-5799-4454-ACDB-D6D330DB1EC4} = {B70AFB57-57C9-46DC-84BE-11B7DDD34B40}
{79BA7C4A-98AA-467E-80D4-0E4F03EE6DDE} = {879F8787-C3BB-43F3-A92D-6D4C7D3A5285}
{F81AE4C4-E044-4225-BD76-385A0DE621FD} = {B70AFB57-57C9-46DC-84BE-11B7DDD34B40}
{F06D4C3A-7825-43A8-832B-6BDE3D355486} = {B70AFB57-57C9-46DC-84BE-11B7DDD34B40}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {049A763A-C891-4E8D-80CF-89DD3E22ADC7}

View File

@@ -33,45 +33,59 @@ namespace k8s
this.kubernetes = kubernetes;
}
public async Task<T> ListAsync<T>(CancellationToken cancel = default(CancellationToken))
public async Task<T> CreateAsync<T>(T obj, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await this.kubernetes.ListClusterCustomObjectWithHttpMessagesAsync(this.group, this.version, this.plural, cancellationToken: cancel).ConfigureAwait(false);
var resp = await kubernetes.CreateClusterCustomObjectWithHttpMessagesAsync(obj, group, version, plural, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
}
public async Task<T> ListNamespacedAsync<T>(string ns, CancellationToken cancel = default(CancellationToken))
public async Task<T> CreateNamespacedAsync<T>(T obj, string ns, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await this.kubernetes.ListNamespacedCustomObjectWithHttpMessagesAsync(this.group, this.version, ns, this.plural, cancellationToken: cancel).ConfigureAwait(false);
var resp = await kubernetes.CreateNamespacedCustomObjectWithHttpMessagesAsync(obj, group, version, ns, plural, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
}
public async Task<T> ReadNamespacedAsync<T>(string ns, string name, CancellationToken cancel = default(CancellationToken))
public async Task<T> ListAsync<T>(CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await this.kubernetes.GetNamespacedCustomObjectWithHttpMessagesAsync(this.group, this.version, ns, this.plural, name, cancellationToken: cancel).ConfigureAwait(false);
var resp = await kubernetes.ListClusterCustomObjectWithHttpMessagesAsync(group, version, plural, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
}
public async Task<T> ReadAsync<T>(string name, CancellationToken cancel = default(CancellationToken))
public async Task<T> ListNamespacedAsync<T>(string ns, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await this.kubernetes.GetClusterCustomObjectWithHttpMessagesAsync(this.group, this.version, this.plural, name, cancellationToken: cancel).ConfigureAwait(false);
var resp = await kubernetes.ListNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
}
public async Task<T> DeleteAsync<T>(string name, CancellationToken cancel = default(CancellationToken))
public async Task<T> ReadNamespacedAsync<T>(string ns, string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await this.kubernetes.DeleteClusterCustomObjectWithHttpMessagesAsync(this.group, this.version, this.plural, name, cancellationToken: cancel).ConfigureAwait(false);
var resp = await kubernetes.GetNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
}
public async Task<T> DeleteNamespacedAsync<T>(string ns, string name, CancellationToken cancel = default(CancellationToken))
public async Task<T> ReadAsync<T>(string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await this.kubernetes.DeleteNamespacedCustomObjectWithHttpMessagesAsync(this.group, this.version, ns, this.plural, name, cancellationToken: cancel).ConfigureAwait(false);
var resp = await kubernetes.GetClusterCustomObjectWithHttpMessagesAsync(group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
}
public async Task<T> DeleteAsync<T>(string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.DeleteClusterCustomObjectWithHttpMessagesAsync(group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
}
public async Task<T> DeleteNamespacedAsync<T>(string ns, string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.DeleteNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return SafeJsonConvert.DeserializeObject<T>(resp.Body.ToString());
}
@@ -83,7 +97,7 @@ namespace k8s
protected virtual void Dispose(bool disposing)
{
this.kubernetes.Dispose();
kubernetes.Dispose();
}
}
}

View File

@@ -465,6 +465,85 @@ namespace k8s.E2E
reportingInstance: "38"), "default").ConfigureAwait(false);
}
[MinikubeFact]
public async void GenericTest()
{
var namespaceParameter = "default";
var podName = "k8scsharp-e2e-generic-pod";
var client = CreateClient();
var genericPods = new GenericClient(client, "", "v1", "pods");
void Cleanup()
{
var pods = client.ListNamespacedPod(namespaceParameter);
while (pods.Items.Any(p => p.Metadata.Name == podName))
{
try
{
client.DeleteNamespacedPod(podName, namespaceParameter);
}
catch (HttpOperationException e)
{
if (e.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return;
}
}
}
}
try
{
Cleanup();
await genericPods.CreateNamespacedAsync(
new V1Pod()
{
Metadata = new V1ObjectMeta { Name = podName, },
Spec = new V1PodSpec
{
Containers = new[] { new V1Container() { Name = "k8scsharp-e2e", Image = "nginx", }, },
},
},
namespaceParameter).ConfigureAwait(false);
var pods = await genericPods.ListNamespacedAsync<V1PodList>(namespaceParameter).ConfigureAwait(false);
Assert.Contains(pods.Items, p => p.Metadata.Name == podName);
int retry = 5;
while (retry-- > 0)
{
try
{
await genericPods.DeleteNamespacedAsync<V1Pod>(namespaceParameter, podName).ConfigureAwait(false);
}
catch (HttpOperationException e)
{
if (e.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return;
}
}
pods = await genericPods.ListNamespacedAsync<V1PodList>(namespaceParameter).ConfigureAwait(false);
if (!pods.Items.Any(p => p.Metadata.Name == podName))
{
break;
}
await Task.Delay(TimeSpan.FromSeconds(2.5)).ConfigureAwait(false);
}
Assert.DoesNotContain(pods.Items, p => p.Metadata.Name == podName);
}
finally
{
Cleanup();
}
}
private static IKubernetes CreateClient()
{
return new Kubernetes(KubernetesClientConfiguration.BuildDefaultConfig());