Skip to content

Commit 553f6ae

Browse files
add-dynamic-client-examples
1 parent 7bc9f78 commit 553f6ae

File tree

6 files changed

+623
-0
lines changed

6 files changed

+623
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Copyright 2021 The Kubernetes Authors.
2+
#
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+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
This example demonstrates the following:
17+
- Creation of a cluster scoped custom resource definition (CRD) using dynamic-client
18+
- Creation of custom resources (CR) using the above created CRD
19+
- List, patch(update), delete the custom resources
20+
- Delete the custom resource defintion
21+
"""
22+
23+
from kubernetes import config, dynamic
24+
from kubernetes.dynamic.exceptions import ResourceNotFoundError
25+
from kubernetes.client import api_client
26+
import time
27+
28+
29+
def main():
30+
# Creating a dynamic client
31+
client = dynamic.DynamicClient(
32+
api_client.ApiClient(configuration=config.load_kube_config())
33+
)
34+
35+
# fetching the custom resource definition (CRD) api
36+
crd_api = client.resources.get(
37+
api_version="apiextensions.k8s.io/v1beta1", kind="CustomResourceDefinition"
38+
)
39+
40+
# Creating a Namespaced CRD named "ingressroutes.apps.example.com"
41+
name = "ingressroutes.apps.example.com"
42+
43+
crd_manifest = {
44+
"apiVersion": "apiextensions.k8s.io/v1beta1",
45+
"kind": "CustomResourceDefinition",
46+
"metadata": {
47+
"name": name,
48+
},
49+
"spec": {
50+
"group": "apps.example.com",
51+
"names": {
52+
"kind": "IngressRoute",
53+
"listKind": "IngressRouteList",
54+
"plural": "ingressroutes",
55+
"singular": "ingressroute",
56+
},
57+
"scope": "Cluster",
58+
"version": "v1",
59+
"subresources": {"status": {}},
60+
},
61+
}
62+
63+
crd_creation_respone = crd_api.create(crd_manifest)
64+
print(
65+
"\n[INFO] custom resource definition `ingressroutes.apps.example.com` created\n"
66+
)
67+
print("%s\t\t%s" % ("SCOPE", "NAME"))
68+
print(
69+
"%s\t\t%s\n"
70+
% (crd_creation_respone.spec.scope, crd_creation_respone.metadata.name)
71+
)
72+
73+
# Fetching the "ingressroutes" CRD api
74+
75+
try:
76+
ingressroute_api = client.resources.get(
77+
api_version="apps.example.com/v1", kind="IngressRoute"
78+
)
79+
except ResourceNotFoundError:
80+
# Need to wait a sec for the discovery layer to get updated
81+
time.sleep(2)
82+
83+
ingressroute_api = client.resources.get(
84+
api_version="apps.example.com/v1", kind="IngressRoute"
85+
)
86+
87+
# Creating a custom resource (CR) `ingress-route-*`, using the above CRD `ingressroutes.apps.example.com`
88+
89+
ingressroute_manifest_one = {
90+
"apiVersion": "apps.example.com/v1",
91+
"kind": "IngressRoute",
92+
"metadata": {
93+
"name": "ingress-route-one",
94+
},
95+
"spec": {},
96+
}
97+
98+
ingressroute_manifest_second = {
99+
"apiVersion": "apps.example.com/v1",
100+
"kind": "IngressRoute",
101+
"metadata": {
102+
"name": "ingress-route-second",
103+
},
104+
"spec": {},
105+
}
106+
107+
ingressroute_api.create(body=ingressroute_manifest_one)
108+
ingressroute_api.create(body=ingressroute_manifest_second)
109+
print("\n[INFO] custom resources `ingress-route-*` created\n")
110+
111+
# Listing the `ingress-route-*` custom resources
112+
113+
ingress_routes_list = ingressroute_api.get()
114+
print("%s\t\t\t\t%s" % ("NAME", "SPEC"))
115+
for item in ingress_routes_list.items:
116+
print("%s\t\t%s" % (item.metadata.name, item.spec))
117+
118+
# Patching the ingressroutes custom resources
119+
120+
ingressroute_manifest_one["spec"]["entrypoints"] = ["websecure"]
121+
ingressroute_manifest_second["spec"]["entrypoints"] = ["web"]
122+
123+
patch_ingressroute_one = ingressroute_api.patch(
124+
body=ingressroute_manifest_one, content_type="application/merge-patch+json"
125+
)
126+
patch_ingressroute_second = ingressroute_api.patch(
127+
body=ingressroute_manifest_second, content_type="application/merge-patch+json"
128+
)
129+
130+
print("\n[INFO] custom resources `ingress-route-*` patched\n")
131+
patched_ingress_routes_list = ingressroute_api.get()
132+
print("%s\t\t\t\t%s" % ("NAME", "SPEC"))
133+
for item in patched_ingress_routes_list.items:
134+
print("%s\t\t%s" % (item.metadata.name, item.spec))
135+
136+
# Deleting the ingressroutes custom resources
137+
138+
delete_ingressroute_one = ingressroute_api.delete(name="ingress-route-one")
139+
delete_ingressroute_second = ingressroute_api.delete(name="ingress-route-second")
140+
141+
print("\n[INFO] custom resources `ingress-route-*` deleted")
142+
143+
# Deleting the ingressroutes.apps.example.com custom resource definition
144+
145+
crd_api.delete(name=name)
146+
print(
147+
"\n[INFO] custom resource definition `ingressroutes.apps.example.com` deleted"
148+
)
149+
150+
151+
if __name__ == "__main__":
152+
main()

examples/dynamic-client/configmap.py

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Copyright 2021 The Kubernetes Authors.
2+
#
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+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
This example demonstrates the following:
17+
- Creation of a k8s configmap using dynamic-client
18+
- List, patch(update), delete the configmap
19+
"""
20+
21+
from kubernetes import config, dynamic
22+
from kubernetes.client import api_client
23+
24+
25+
def main():
26+
# Creating a dynamic client
27+
client = dynamic.DynamicClient(
28+
api_client.ApiClient(configuration=config.load_kube_config())
29+
)
30+
31+
# fetching the configmap api
32+
api = client.resources.get(api_version="v1", kind="ConfigMap")
33+
34+
configmap_name = "test-configmap"
35+
36+
configmap_manifest = {
37+
"kind": "ConfigMap",
38+
"apiVersion": "v1",
39+
"metadata": {
40+
"name": configmap_name,
41+
"labels": {
42+
"foo": "bar",
43+
},
44+
},
45+
"data": {
46+
"config.json": '{"command":"/usr/bin/mysqld_safe"}',
47+
"frontend.cnf": "[mysqld]\nbind-address = 10.0.0.3\n",
48+
},
49+
}
50+
51+
# Creating configmap `test-configmap` in the `default` namespace
52+
53+
configmap = api.create(body=configmap_manifest, namespace="default")
54+
55+
print("\n[INFO] configmap `test-configmap` created\n")
56+
57+
# Listing the configmaps in the `default` namespace
58+
59+
configmap_list = api.get(
60+
name=configmap_name, namespace="default", label_selector="foo=bar"
61+
)
62+
63+
print("NAME:\n%s\n" % (configmap_list.metadata.name))
64+
print("DATA:\n%s\n" % (configmap_list.data))
65+
66+
# Updating the configmap's data, `config.json`
67+
68+
configmap_manifest["data"]["config.json"] = "{}"
69+
70+
configmap_patched = api.patch(
71+
name=configmap_name, namespace="default", body=configmap_manifest
72+
)
73+
74+
print("\n[INFO] configmap `test-configmap` patched\n")
75+
print("NAME:\n%s\n" % (configmap_patched.metadata.name))
76+
print("DATA:\n%s\n" % (configmap_patched.data))
77+
78+
# Deleting configmap `test-configmap` from the `default` namespace
79+
80+
configmap_deleted = api.delete(name=configmap_name, body={}, namespace="default")
81+
print("\n[INFO] configmap `test-configmap` deleted\n")
82+
83+
84+
if __name__ == "__main__":
85+
main()

0 commit comments

Comments
 (0)