Skip to content

Commit 656a028

Browse files
authored
Merge pull request kubernetes-client#1528 from yue9944882/feat/dynamic-kubernetes-api
Feat: Dynamic kubernetes api for classless api requesting
2 parents c01c31e + 0e10890 commit 656a028

10 files changed

Lines changed: 687 additions & 1 deletion

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.kubernetes.client.e2e.dynamic
2+
3+
4+
import io.kubernetes.client.openapi.models.V1Namespace
5+
import io.kubernetes.client.openapi.models.V1ObjectMeta
6+
import io.kubernetes.client.util.ClientBuilder
7+
import io.kubernetes.client.util.generic.dynamic.DynamicKubernetesApi
8+
import io.kubernetes.client.util.generic.dynamic.Dynamics
9+
import spock.lang.Specification
10+
11+
class DynamicApiTest extends Specification {
12+
def "Create Namespace then Delete should work"() {
13+
given:
14+
def apiClient = ClientBuilder.defaultClient()
15+
def dynamicApi = new DynamicKubernetesApi("", "v1", "namespaces", apiClient)
16+
def namespaceFoo = new V1Namespace().metadata(new V1ObjectMeta().name("e2e-dynamic"))
17+
when:
18+
def createdNamespace = dynamicApi.create(Dynamics.newFromJson(apiClient.getJSON().serialize(namespaceFoo)))
19+
then:
20+
createdNamespace != null
21+
when:
22+
def deleted = dynamicApi.delete("e2e-dynamic").throwsApiException().getObject()
23+
then:
24+
deleted != null
25+
}
26+
}

examples/examples-release-12/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<groupId>io.kubernetes</groupId>
66
<artifactId>client-java-examples-parent</artifactId>
77
<version>11.0.1-SNAPSHOT</version>
8-
<relativePath>..</relativePath>
8+
<relativePath>../pom.xml</relativePath>
99
</parent>
1010

1111
<artifactId>client-java-examples-release-12</artifactId>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
Copyright 2021 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.examples;
14+
15+
import java.io.FileReader;
16+
import java.io.IOException;
17+
18+
import io.kubernetes.client.openapi.ApiClient;
19+
import io.kubernetes.client.openapi.ApiException;
20+
import io.kubernetes.client.util.ClientBuilder;
21+
import io.kubernetes.client.util.KubeConfig;
22+
import io.kubernetes.client.util.generic.dynamic.DynamicKubernetesApi;
23+
import io.kubernetes.client.util.generic.dynamic.DynamicKubernetesObject;
24+
25+
public class DynamicClientExample {
26+
27+
public static void main(String[] args) throws IOException, ApiException {
28+
29+
ApiClient apiClient = ClientBuilder.standard().build();
30+
31+
// retrieving the latest state of the default namespace
32+
DynamicKubernetesApi dynamicApi = new DynamicKubernetesApi("", "v1", "namespaces", apiClient);
33+
DynamicKubernetesObject defaultNamespace = dynamicApi.get("default")
34+
.throwsApiException()
35+
.getObject();
36+
37+
// attaching a "foo=bar" label to the default namespace
38+
defaultNamespace.setMetadata(defaultNamespace.getMetadata().putLabelsItem("foo", "bar"));
39+
DynamicKubernetesObject updatedDefaultNamespace = dynamicApi.update(defaultNamespace)
40+
.throwsApiException()
41+
.getObject();
42+
43+
System.out.println(updatedDefaultNamespace);
44+
45+
apiClient.getHttpClient().connectionPool().evictAll();
46+
}
47+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
Copyright 2021 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.util.generic.dynamic;
14+
15+
import com.google.gson.Gson;
16+
import com.google.gson.TypeAdapter;
17+
import io.kubernetes.client.common.KubernetesListObject;
18+
import io.kubernetes.client.common.KubernetesObject;
19+
import io.kubernetes.client.openapi.ApiClient;
20+
import io.kubernetes.client.util.generic.GenericKubernetesApi;
21+
22+
/**
23+
* DynamicKubernetesApi can be used for reading and writing arbitrary resources without knowing it's
24+
* java definitions.
25+
*/
26+
public class DynamicKubernetesApi
27+
extends GenericKubernetesApi<DynamicKubernetesObject, DynamicKubernetesListObject> {
28+
29+
private final Gson gson;
30+
31+
/**
32+
* Instantiates a new Dynamic kubernetes api.
33+
*
34+
* @param apiGroup the api group
35+
* @param apiVersion the api version
36+
* @param resourcePlural the resource plural
37+
* @param apiClient the api client
38+
*/
39+
public DynamicKubernetesApi(
40+
String apiGroup, String apiVersion, String resourcePlural, ApiClient apiClient) {
41+
super(
42+
DynamicKubernetesObject.class,
43+
DynamicKubernetesListObject.class,
44+
apiGroup,
45+
apiVersion,
46+
resourcePlural,
47+
apiClient);
48+
TypeAdapter<KubernetesObject> objAdapter =
49+
apiClient.getJSON().getGson().getAdapter(KubernetesObject.class);
50+
TypeAdapter<KubernetesListObject> objListAdapter =
51+
apiClient.getJSON().getGson().getAdapter(KubernetesListObject.class);
52+
if (!DynamicKubernetesTypeAdaptorFactory.GenericListObjectCreator.class.equals(
53+
objListAdapter.getClass())
54+
|| !DynamicKubernetesTypeAdaptorFactory.GenericObjectCreator.class.equals(
55+
objAdapter.getClass())) {
56+
apiClient
57+
.getJSON()
58+
.setGson(
59+
apiClient
60+
.getJSON()
61+
.getGson()
62+
.newBuilder()
63+
.registerTypeAdapterFactory(new DynamicKubernetesTypeAdaptorFactory())
64+
.create());
65+
}
66+
gson = apiClient.getJSON().getGson();
67+
}
68+
69+
/**
70+
* Gets gson instance.
71+
*
72+
* @return the gson
73+
*/
74+
public Gson getGson() {
75+
return gson;
76+
}
77+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
Copyright 2021 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.util.generic.dynamic;
14+
15+
import com.google.gson.JsonElement;
16+
import com.google.gson.JsonObject;
17+
import io.kubernetes.client.common.KubernetesListObject;
18+
import io.kubernetes.client.openapi.Configuration;
19+
import io.kubernetes.client.openapi.models.V1ListMeta;
20+
import java.util.ArrayList;
21+
import java.util.List;
22+
import java.util.Objects;
23+
24+
/**
25+
* DynamicKubernetesListObject is a wrapper for {@link JsonObject} that fits the common kubernetes
26+
* list type interface {@link KubernetesListObject}.
27+
*/
28+
public class DynamicKubernetesListObject implements KubernetesListObject {
29+
30+
public DynamicKubernetesListObject() {
31+
this(new JsonObject());
32+
}
33+
34+
public DynamicKubernetesListObject(JsonObject obj) {
35+
this.raw = obj;
36+
}
37+
38+
private final JsonObject raw;
39+
40+
@Override
41+
public V1ListMeta getMetadata() {
42+
return Configuration.getDefaultApiClient()
43+
.getJSON()
44+
.getGson()
45+
.fromJson(this.raw.get("metadata"), V1ListMeta.class);
46+
}
47+
48+
@Override
49+
public String getApiVersion() {
50+
return this.raw.get("apiVersion").getAsString();
51+
}
52+
53+
@Override
54+
public String getKind() {
55+
return this.raw.get("kind").getAsString();
56+
}
57+
58+
@Override
59+
public List<DynamicKubernetesObject> getItems() {
60+
List<DynamicKubernetesObject> list = new ArrayList<>();
61+
for (JsonElement e : this.raw.get("items").getAsJsonArray()) {
62+
list.add(new DynamicKubernetesObject(e.getAsJsonObject()));
63+
}
64+
return list;
65+
}
66+
67+
public JsonObject getRaw() {
68+
return raw;
69+
}
70+
71+
public void setApiVersion(String apiVersion) {
72+
this.raw.addProperty("apiVersion", apiVersion);
73+
}
74+
75+
public void setKind(String kind) {
76+
this.raw.addProperty("kind", kind);
77+
}
78+
79+
public void setMetadata(V1ListMeta objectMeta) {
80+
this.raw.add(
81+
"metadata", Configuration.getDefaultApiClient().getJSON().getGson().toJsonTree(objectMeta));
82+
}
83+
84+
@Override
85+
public boolean equals(Object o) {
86+
if (this == o) return true;
87+
if (o == null || getClass() != o.getClass()) return false;
88+
DynamicKubernetesListObject that = (DynamicKubernetesListObject) o;
89+
return Objects.equals(raw, that.raw);
90+
}
91+
92+
@Override
93+
public int hashCode() {
94+
return Objects.hash(raw);
95+
}
96+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
Copyright 2021 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.util.generic.dynamic;
14+
15+
import com.google.gson.JsonObject;
16+
import io.kubernetes.client.common.KubernetesObject;
17+
import io.kubernetes.client.openapi.Configuration;
18+
import io.kubernetes.client.openapi.models.V1ObjectMeta;
19+
import java.util.Objects;
20+
21+
/**
22+
* DynamicKubernetesObject is a wrapper for {@link JsonObject} that fits the common kubernetes type
23+
* interface {@link KubernetesObject}.
24+
*/
25+
public class DynamicKubernetesObject implements KubernetesObject {
26+
27+
public DynamicKubernetesObject() {
28+
this(new JsonObject());
29+
}
30+
31+
public DynamicKubernetesObject(JsonObject obj) {
32+
this.raw = obj;
33+
}
34+
35+
private final JsonObject raw;
36+
37+
@Override
38+
public V1ObjectMeta getMetadata() {
39+
return Configuration.getDefaultApiClient()
40+
.getJSON()
41+
.getGson()
42+
.fromJson(this.raw.get("metadata"), V1ObjectMeta.class);
43+
}
44+
45+
@Override
46+
public String getApiVersion() {
47+
return this.raw.get("apiVersion").getAsString();
48+
}
49+
50+
@Override
51+
public String getKind() {
52+
return this.raw.get("kind").getAsString();
53+
}
54+
55+
public JsonObject getRaw() {
56+
return raw;
57+
}
58+
59+
public void setApiVersion(String apiVersion) {
60+
this.raw.addProperty("apiVersion", apiVersion);
61+
}
62+
63+
public void setKind(String kind) {
64+
this.raw.addProperty("kind", kind);
65+
}
66+
67+
public void setMetadata(V1ObjectMeta objectMeta) {
68+
this.raw.add(
69+
"metadata", Configuration.getDefaultApiClient().getJSON().getGson().toJsonTree(objectMeta));
70+
}
71+
72+
@Override
73+
public boolean equals(Object o) {
74+
if (this == o) return true;
75+
if (o == null || getClass() != o.getClass()) return false;
76+
DynamicKubernetesObject that = (DynamicKubernetesObject) o;
77+
return Objects.equals(raw, that.raw);
78+
}
79+
80+
@Override
81+
public int hashCode() {
82+
return Objects.hash(raw);
83+
}
84+
}

0 commit comments

Comments
 (0)