Skip to content

Commit 2c2acf5

Browse files
authored
Merge pull request #1251 from yue9944882/kubectl-get
Feat: Kubectl get implementation
2 parents d940b0c + 4af3e03 commit 2c2acf5

File tree

5 files changed

+355
-18
lines changed

5 files changed

+355
-18
lines changed

e2e/src/test/groovy/io/kubernetes/client/e2e/kubectl/KubectlApplyTest.groovy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ class KubectlApplyTest extends Specification {
2020
.metadata(new V1ObjectMeta().name("apply-foo")))
2121
.execute()
2222
expect:
23-
appliedNamespace != null
23+
Kubectl.get(V1Namespace.class)
24+
.apiClient(apiClient)
25+
.name("apply-foo")
26+
.execute() != null
2427
}
2528

2629
}

e2e/src/test/groovy/io/kubernetes/client/e2e/kubectl/KubectlCreateTest.groovy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ class KubectlCreateTest extends Specification {
1818
.metadata(new V1ObjectMeta().name("create-foo")))
1919
.execute()
2020
expect:
21-
createdNamespace != null
21+
Kubectl.get(V1Namespace.class)
22+
.apiClient(apiClient)
23+
.name("create-foo")
24+
.execute() != null
2225
}
2326

2427
}

extended/src/main/java/io/kubernetes/client/extended/kubectl/Kubectl.java

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@
2828
* kubectl commands.
2929
*/
3030
public class Kubectl {
31+
32+
/** Equivalent for `kubectl get` */
33+
public static <ApiType extends KubernetesObject> KubectlGet<ApiType> get(
34+
Class<ApiType> apiTypeClass) {
35+
return new KubectlGet<>(apiTypeClass);
36+
}
37+
3138
/** Equivalent for `kubectl drain` */
3239
public static KubectlDrain drain() {
3340
return new KubectlDrain();
@@ -70,6 +77,7 @@ public static <ApiType extends KubernetesObject> KubectlReplace<ApiType> replace
7077
public static KubectlApply apply() {
7178
return new KubectlApply();
7279
}
80+
7381
/**
7482
* Equivalent for `kubectl top`
7583
*
@@ -220,15 +228,38 @@ protected void refreshDiscovery() throws KubectlException {
220228
}
221229
}
222230

223-
protected GenericKubernetesApi<? extends KubernetesObject, KubernetesListObject> getGenericApi(
224-
Class<? extends KubernetesObject> apiTypeClass) {
231+
protected <ApiType extends KubernetesObject>
232+
GenericKubernetesApi<ApiType, ? extends KubernetesListObject> getGenericApi(
233+
Class<ApiType> apiTypeClass) throws KubectlException {
234+
235+
// load list type class dynamically from class-loader
236+
String apiListTypeClassName = apiTypeClass.getName() + "List";
237+
try {
238+
Class<? extends KubernetesListObject> apiTypeListClass;
239+
apiTypeListClass =
240+
(Class<? extends KubernetesListObject>)
241+
apiTypeClass.getClassLoader().loadClass(apiListTypeClassName);
242+
return getGenericApi(apiTypeClass, apiTypeListClass);
243+
} catch (ClassNotFoundException e) {
244+
throw new KubectlException(
245+
new StringBuilder()
246+
.append("No such api list type class ")
247+
.append(apiListTypeClassName)
248+
.append(", consider explicitly load the class by apiListTypeClass()?")
249+
.toString());
250+
}
251+
}
252+
253+
protected <ApiType extends KubernetesObject, ApiListType extends KubernetesListObject>
254+
GenericKubernetesApi<ApiType, ApiListType> getGenericApi(
255+
Class<ApiType> apiTypeClass, Class<ApiListType> apiListTypeClass) {
225256
GroupVersionResource groupVersionResource =
226257
ModelMapper.getGroupVersionResourceByClass(apiTypeClass);
227258

228-
GenericKubernetesApi<? extends KubernetesObject, KubernetesListObject> api =
259+
GenericKubernetesApi<ApiType, ApiListType> api =
229260
new GenericKubernetesApi<>(
230261
apiTypeClass,
231-
KubernetesListObject.class,
262+
apiListTypeClass,
232263
groupVersionResource.getGroup(),
233264
groupVersionResource.getVersion(),
234265
groupVersionResource.getResource(),
@@ -263,18 +294,7 @@ public T name(String name) {
263294
}
264295

265296
protected GenericKubernetesApi<ApiType, KubernetesListObject> getGenericApi() {
266-
GroupVersionResource groupVersionResource =
267-
ModelMapper.getGroupVersionResourceByClass(apiTypeClass);
268-
269-
GenericKubernetesApi<ApiType, KubernetesListObject> api =
270-
new GenericKubernetesApi<>(
271-
apiTypeClass,
272-
KubernetesListObject.class,
273-
groupVersionResource.getGroup(),
274-
groupVersionResource.getVersion(),
275-
groupVersionResource.getResource(),
276-
apiClient);
277-
return api;
297+
return getGenericApi(apiTypeClass, KubernetesListObject.class);
278298
}
279299
}
280300

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.kubernetes.client.extended.kubectl;
14+
15+
import io.kubernetes.client.common.KubernetesListObject;
16+
import io.kubernetes.client.common.KubernetesObject;
17+
import io.kubernetes.client.extended.kubectl.exception.KubectlException;
18+
import io.kubernetes.client.openapi.ApiException;
19+
import io.kubernetes.client.util.generic.GenericKubernetesApi;
20+
import io.kubernetes.client.util.generic.options.ListOptions;
21+
import java.util.List;
22+
import org.apache.commons.lang.StringUtils;
23+
24+
public class KubectlGet<ApiType extends KubernetesObject>
25+
extends Kubectl.ApiClientBuilder<KubectlGet<ApiType>>
26+
implements Kubectl.Executable<List<ApiType>> {
27+
28+
private String namespace;
29+
private ListOptions listOptions;
30+
private Class<ApiType> apiTypeClass;
31+
private Class<? extends KubernetesListObject> apiTypeListClass;
32+
33+
KubectlGet(Class<ApiType> apiTypeClass) {
34+
this.apiTypeClass = apiTypeClass;
35+
this.listOptions = new ListOptions();
36+
}
37+
38+
public KubectlGet<ApiType> apiListTypeClass(
39+
Class<? extends KubernetesListObject> apiTypeListClass) {
40+
this.apiTypeListClass = apiTypeListClass;
41+
return this;
42+
}
43+
44+
public KubectlGet<ApiType> options(ListOptions listOptions) {
45+
this.listOptions = listOptions;
46+
return this;
47+
}
48+
49+
public KubectlGet<ApiType> namespace(String namespace) {
50+
this.namespace = namespace;
51+
return this;
52+
}
53+
54+
public KubectlGetSingle name(String name) {
55+
return new KubectlGetSingle(name);
56+
}
57+
58+
@Override
59+
public List<ApiType> execute() throws KubectlException {
60+
GenericKubernetesApi<ApiType, ? extends KubernetesListObject> api =
61+
apiTypeListClass == null
62+
? getGenericApi(apiTypeClass)
63+
: getGenericApi(apiTypeClass, apiTypeListClass);
64+
try {
65+
if (isNamespaced()) {
66+
return (List<ApiType>)
67+
api.list(namespace, listOptions)
68+
.onFailure(
69+
errorStatus -> {
70+
throw new ApiException(errorStatus.toString());
71+
})
72+
.getObject()
73+
.getItems();
74+
75+
} else {
76+
return (List<ApiType>)
77+
api.list(listOptions)
78+
.onFailure(
79+
errorStatus -> {
80+
throw new ApiException(errorStatus.toString());
81+
})
82+
.getObject()
83+
.getItems();
84+
}
85+
} catch (ApiException e) {
86+
throw new KubectlException(e);
87+
}
88+
}
89+
90+
private boolean isNamespaced() {
91+
return !StringUtils.isEmpty(namespace);
92+
}
93+
94+
public class KubectlGetSingle extends Kubectl.ResourceBuilder<ApiType, KubectlGetSingle>
95+
implements Kubectl.Executable<ApiType> {
96+
97+
private KubectlGetSingle(String name) {
98+
super(KubectlGet.this.apiTypeClass);
99+
KubectlGetSingle.this.name = name;
100+
KubectlGetSingle.this.namespace = KubectlGet.this.namespace;
101+
KubectlGetSingle.this.apiClient = KubectlGet.this.apiClient;
102+
KubectlGetSingle.this.skipDiscovery = KubectlGet.this.skipDiscovery;
103+
}
104+
105+
private boolean isNamespaced() {
106+
return !StringUtils.isEmpty(namespace);
107+
}
108+
109+
@Override
110+
public ApiType execute() throws KubectlException {
111+
GenericKubernetesApi<ApiType, ? extends KubernetesListObject> api =
112+
getGenericApi(KubectlGetSingle.this.apiTypeClass);
113+
try {
114+
if (isNamespaced()) {
115+
return api.get(KubectlGetSingle.this.namespace, KubectlGetSingle.this.name)
116+
.onFailure(
117+
errorStatus -> {
118+
throw new ApiException(errorStatus.toString());
119+
})
120+
.getObject();
121+
122+
} else {
123+
return api.get(KubectlGetSingle.this.name)
124+
.onFailure(
125+
errorStatus -> {
126+
throw new ApiException(errorStatus.toString());
127+
})
128+
.getObject();
129+
}
130+
} catch (ApiException e) {
131+
throw new KubectlException(e);
132+
}
133+
}
134+
}
135+
}

0 commit comments

Comments
 (0)