Skip to content

Commit 2147fb4

Browse files
Refactor to use generic Get method with GenericClient
Co-authored-by: brendandburns <[email protected]>
1 parent 218395a commit 2147fb4

File tree

3 files changed

+108
-156
lines changed

3 files changed

+108
-156
lines changed
Lines changed: 18 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,28 @@
1-
using k8s.Models;
2-
31
namespace k8s.kubectl.beta;
42

53
public partial class AsyncKubectl
64
{
75
/// <summary>
8-
/// Get a pod by name in a namespace.
9-
/// </summary>
10-
/// <param name="name">The name of the pod.</param>
11-
/// <param name="namespace">The namespace of the pod. Defaults to "default".</param>
12-
/// <param name="cancellationToken">Cancellation token.</param>
13-
/// <returns>The pod.</returns>
14-
public async Task<V1Pod> GetPodAsync(string name, string @namespace = "default", CancellationToken cancellationToken = default)
15-
{
16-
return await client.CoreV1.ReadNamespacedPodAsync(name, @namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
17-
}
18-
19-
/// <summary>
20-
/// Get a deployment by name in a namespace.
21-
/// </summary>
22-
/// <param name="name">The name of the deployment.</param>
23-
/// <param name="namespace">The namespace of the deployment. Defaults to "default".</param>
24-
/// <param name="cancellationToken">Cancellation token.</param>
25-
/// <returns>The deployment.</returns>
26-
public async Task<V1Deployment> GetDeploymentAsync(string name, string @namespace = "default", CancellationToken cancellationToken = default)
27-
{
28-
return await client.AppsV1.ReadNamespacedDeploymentAsync(name, @namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
29-
}
30-
31-
/// <summary>
32-
/// Get a service by name in a namespace.
33-
/// </summary>
34-
/// <param name="name">The name of the service.</param>
35-
/// <param name="namespace">The namespace of the service. Defaults to "default".</param>
36-
/// <param name="cancellationToken">Cancellation token.</param>
37-
/// <returns>The service.</returns>
38-
public async Task<V1Service> GetServiceAsync(string name, string @namespace = "default", CancellationToken cancellationToken = default)
39-
{
40-
return await client.CoreV1.ReadNamespacedServiceAsync(name, @namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
41-
}
42-
43-
/// <summary>
44-
/// Get a namespace by name.
45-
/// </summary>
46-
/// <param name="name">The name of the namespace.</param>
47-
/// <param name="cancellationToken">Cancellation token.</param>
48-
/// <returns>The namespace.</returns>
49-
public async Task<V1Namespace> GetNamespaceAsync(string name, CancellationToken cancellationToken = default)
50-
{
51-
return await client.CoreV1.ReadNamespaceAsync(name, cancellationToken: cancellationToken).ConfigureAwait(false);
52-
}
53-
54-
/// <summary>
55-
/// Get a node by name.
56-
/// </summary>
57-
/// <param name="name">The name of the node.</param>
58-
/// <param name="cancellationToken">Cancellation token.</param>
59-
/// <returns>The node.</returns>
60-
public async Task<V1Node> GetNodeAsync(string name, CancellationToken cancellationToken = default)
61-
{
62-
return await client.CoreV1.ReadNodeAsync(name, cancellationToken: cancellationToken).ConfigureAwait(false);
63-
}
64-
65-
/// <summary>
66-
/// Get a config map by name in a namespace.
67-
/// </summary>
68-
/// <param name="name">The name of the config map.</param>
69-
/// <param name="namespace">The namespace of the config map. Defaults to "default".</param>
70-
/// <param name="cancellationToken">Cancellation token.</param>
71-
/// <returns>The config map.</returns>
72-
public async Task<V1ConfigMap> GetConfigMapAsync(string name, string @namespace = "default", CancellationToken cancellationToken = default)
73-
{
74-
return await client.CoreV1.ReadNamespacedConfigMapAsync(name, @namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
75-
}
76-
77-
/// <summary>
78-
/// Get a secret by name in a namespace.
6+
/// Get a Kubernetes resource by name.
797
/// </summary>
80-
/// <param name="name">The name of the secret.</param>
81-
/// <param name="namespace">The namespace of the secret. Defaults to "default".</param>
8+
/// <typeparam name="T">The type of Kubernetes resource to get.</typeparam>
9+
/// <param name="name">The name of the resource.</param>
10+
/// <param name="namespace">The namespace of the resource (for namespaced resources). Optional.</param>
8211
/// <param name="cancellationToken">Cancellation token.</param>
83-
/// <returns>The secret.</returns>
84-
public async Task<V1Secret> GetSecretAsync(string name, string @namespace = "default", CancellationToken cancellationToken = default)
12+
/// <returns>The requested resource.</returns>
13+
public async Task<T> GetAsync<T>(string name, string? @namespace = null, CancellationToken cancellationToken = default)
14+
where T : IKubernetesObject
8515
{
86-
return await client.CoreV1.ReadNamespacedSecretAsync(name, @namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
16+
var metadata = typeof(T).GetKubernetesTypeMetadata();
17+
var genericClient = new GenericClient(client, metadata.Group, metadata.ApiVersion, metadata.PluralName, disposeClient: false);
18+
19+
if (@namespace != null)
20+
{
21+
return await genericClient.ReadNamespacedAsync<T>(@namespace, name, cancellationToken).ConfigureAwait(false);
22+
}
23+
else
24+
{
25+
return await genericClient.ReadAsync<T>(name, cancellationToken).ConfigureAwait(false);
26+
}
8727
}
8828
}
Lines changed: 8 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,17 @@
1-
using k8s.Models;
2-
31
namespace k8s.kubectl.beta;
42

53
public partial class Kubectl
64
{
75
/// <summary>
8-
/// Get a pod by name in a namespace.
9-
/// </summary>
10-
/// <param name="name">The name of the pod.</param>
11-
/// <param name="namespace">The namespace of the pod. Defaults to "default".</param>
12-
/// <returns>The pod.</returns>
13-
public V1Pod GetPod(string name, string @namespace = "default")
14-
{
15-
return client.GetPodAsync(name, @namespace).GetAwaiter().GetResult();
16-
}
17-
18-
/// <summary>
19-
/// Get a deployment by name in a namespace.
20-
/// </summary>
21-
/// <param name="name">The name of the deployment.</param>
22-
/// <param name="namespace">The namespace of the deployment. Defaults to "default".</param>
23-
/// <returns>The deployment.</returns>
24-
public V1Deployment GetDeployment(string name, string @namespace = "default")
25-
{
26-
return client.GetDeploymentAsync(name, @namespace).GetAwaiter().GetResult();
27-
}
28-
29-
/// <summary>
30-
/// Get a service by name in a namespace.
31-
/// </summary>
32-
/// <param name="name">The name of the service.</param>
33-
/// <param name="namespace">The namespace of the service. Defaults to "default".</param>
34-
/// <returns>The service.</returns>
35-
public V1Service GetService(string name, string @namespace = "default")
36-
{
37-
return client.GetServiceAsync(name, @namespace).GetAwaiter().GetResult();
38-
}
39-
40-
/// <summary>
41-
/// Get a namespace by name.
42-
/// </summary>
43-
/// <param name="name">The name of the namespace.</param>
44-
/// <returns>The namespace.</returns>
45-
public V1Namespace GetNamespace(string name)
46-
{
47-
return client.GetNamespaceAsync(name).GetAwaiter().GetResult();
48-
}
49-
50-
/// <summary>
51-
/// Get a node by name.
52-
/// </summary>
53-
/// <param name="name">The name of the node.</param>
54-
/// <returns>The node.</returns>
55-
public V1Node GetNode(string name)
56-
{
57-
return client.GetNodeAsync(name).GetAwaiter().GetResult();
58-
}
59-
60-
/// <summary>
61-
/// Get a config map by name in a namespace.
62-
/// </summary>
63-
/// <param name="name">The name of the config map.</param>
64-
/// <param name="namespace">The namespace of the config map. Defaults to "default".</param>
65-
/// <returns>The config map.</returns>
66-
public V1ConfigMap GetConfigMap(string name, string @namespace = "default")
67-
{
68-
return client.GetConfigMapAsync(name, @namespace).GetAwaiter().GetResult();
69-
}
70-
71-
/// <summary>
72-
/// Get a secret by name in a namespace.
6+
/// Get a Kubernetes resource by name.
737
/// </summary>
74-
/// <param name="name">The name of the secret.</param>
75-
/// <param name="namespace">The namespace of the secret. Defaults to "default".</param>
76-
/// <returns>The secret.</returns>
77-
public V1Secret GetSecret(string name, string @namespace = "default")
8+
/// <typeparam name="T">The type of Kubernetes resource to get.</typeparam>
9+
/// <param name="name">The name of the resource.</param>
10+
/// <param name="namespace">The namespace of the resource (for namespaced resources). Optional.</param>
11+
/// <returns>The requested resource.</returns>
12+
public T Get<T>(string name, string? @namespace = null)
13+
where T : IKubernetesObject
7814
{
79-
return client.GetSecretAsync(name, @namespace).GetAwaiter().GetResult();
15+
return client.GetAsync<T>(name, @namespace).GetAwaiter().GetResult();
8016
}
8117
}

tests/Kubectl.Tests/KubectlTests.Get.cs

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ public void GetNamespace()
1313
using var kubernetes = MinikubeTests.CreateClient();
1414
var client = new Kubectl(kubernetes);
1515

16-
// Get the default namespace
17-
var ns = client.GetNamespace("default");
16+
// Get the default namespace (cluster-scoped resource, no namespace parameter)
17+
var ns = client.Get<V1Namespace>("default");
1818

1919
Assert.NotNull(ns);
2020
Assert.Equal("default", ns.Metadata.Name);
@@ -55,8 +55,8 @@ public void GetPod()
5555
{
5656
kubernetes.CoreV1.CreateNamespacedPod(pod, namespaceParameter);
5757

58-
// Get the pod using kubectl
59-
var retrievedPod = client.GetPod(podName, namespaceParameter);
58+
// Get the pod using kubectl generic get
59+
var retrievedPod = client.Get<V1Pod>(podName, namespaceParameter);
6060

6161
Assert.NotNull(retrievedPod);
6262
Assert.Equal(podName, retrievedPod.Metadata.Name);
@@ -115,8 +115,8 @@ public void GetService()
115115
{
116116
kubernetes.CoreV1.CreateNamespacedService(service, namespaceParameter);
117117

118-
// Get the service using kubectl
119-
var retrievedService = client.GetService(serviceName, namespaceParameter);
118+
// Get the service using kubectl generic get
119+
var retrievedService = client.Get<V1Service>(serviceName, namespaceParameter);
120120

121121
Assert.NotNull(retrievedService);
122122
Assert.Equal(serviceName, retrievedService.Metadata.Name);
@@ -137,4 +137,80 @@ public void GetService()
137137
}
138138
}
139139
}
140+
141+
[MinikubeFact]
142+
public void GetDeployment()
143+
{
144+
using var kubernetes = MinikubeTests.CreateClient();
145+
var client = new Kubectl(kubernetes);
146+
var namespaceParameter = "default";
147+
var deploymentName = "k8scsharp-e2e-get-deployment";
148+
149+
// Create a test deployment
150+
var deployment = new V1Deployment
151+
{
152+
Metadata = new V1ObjectMeta
153+
{
154+
Name = deploymentName,
155+
NamespaceProperty = namespaceParameter,
156+
},
157+
Spec = new V1DeploymentSpec
158+
{
159+
Replicas = 1,
160+
Selector = new V1LabelSelector
161+
{
162+
MatchLabels = new Dictionary<string, string>
163+
{
164+
{ "app", "test" },
165+
},
166+
},
167+
Template = new V1PodTemplateSpec
168+
{
169+
Metadata = new V1ObjectMeta
170+
{
171+
Labels = new Dictionary<string, string>
172+
{
173+
{ "app", "test" },
174+
},
175+
},
176+
Spec = new V1PodSpec
177+
{
178+
Containers = new[]
179+
{
180+
new V1Container
181+
{
182+
Name = "test",
183+
Image = "nginx:latest",
184+
},
185+
},
186+
},
187+
},
188+
},
189+
};
190+
191+
try
192+
{
193+
kubernetes.AppsV1.CreateNamespacedDeployment(deployment, namespaceParameter);
194+
195+
// Get the deployment using kubectl generic get
196+
var retrievedDeployment = client.Get<V1Deployment>(deploymentName, namespaceParameter);
197+
198+
Assert.NotNull(retrievedDeployment);
199+
Assert.Equal(deploymentName, retrievedDeployment.Metadata.Name);
200+
Assert.Equal(namespaceParameter, retrievedDeployment.Metadata.NamespaceProperty);
201+
Assert.Equal("Deployment", retrievedDeployment.Kind);
202+
}
203+
finally
204+
{
205+
// Cleanup
206+
try
207+
{
208+
kubernetes.AppsV1.DeleteNamespacedDeployment(deploymentName, namespaceParameter);
209+
}
210+
catch
211+
{
212+
// Ignore cleanup errors
213+
}
214+
}
215+
}
140216
}

0 commit comments

Comments
 (0)