Skip to content

Commit def8b28

Browse files
authored
Merge pull request #1448 from Priyankasaggu11929/psaggu-add-dynamic-client-examples
add examples to demonstrate the usage of dynamic client
2 parents b13b350 + 1ff6ece commit def8b28

File tree

6 files changed

+745
-0
lines changed

6 files changed

+745
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
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 custom resource definition (CRD) using dynamic-client
18+
- Creation of cluster scoped custom resources (CR) using the above created CRD
19+
- List, patch (update), delete the custom resources
20+
- Delete the custom resource defintion (CRD)
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/v1", 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/v1",
45+
"kind": "CustomResourceDefinition",
46+
"metadata": {
47+
"name": name,
48+
},
49+
"spec": {
50+
"group": "apps.example.com",
51+
"versions": [
52+
{
53+
"name": "v1",
54+
"schema": {
55+
"openAPIV3Schema": {
56+
"properties": {
57+
"spec": {
58+
"properties": {
59+
"strategy": {"type": "string"},
60+
"virtualhost": {
61+
"properties": {
62+
"fqdn": {"type": "string"},
63+
"tls": {
64+
"properties": {
65+
"secretName": {"type": "string"}
66+
},
67+
"type": "object",
68+
},
69+
},
70+
"type": "object",
71+
},
72+
},
73+
"type": "object",
74+
}
75+
},
76+
"type": "object",
77+
}
78+
},
79+
"served": True,
80+
"storage": True,
81+
}
82+
],
83+
"scope": "Cluster",
84+
"names": {
85+
"plural": "ingressroutes",
86+
"listKind": "IngressRouteList",
87+
"singular": "ingressroute",
88+
"kind": "IngressRoute",
89+
"shortNames": ["ir"],
90+
},
91+
},
92+
}
93+
94+
crd_creation_response = crd_api.create(crd_manifest)
95+
print(
96+
"\n[INFO] custom resource definition `ingressroutes.apps.example.com` created\n"
97+
)
98+
print("%s\t\t%s" % ("SCOPE", "NAME"))
99+
print(
100+
"%s\t\t%s\n"
101+
% (crd_creation_response.spec.scope, crd_creation_response.metadata.name)
102+
)
103+
104+
# Fetching the "ingressroutes" CRD api
105+
106+
try:
107+
ingressroute_api = client.resources.get(
108+
api_version="apps.example.com/v1", kind="IngressRoute"
109+
)
110+
except ResourceNotFoundError:
111+
# Need to wait a sec for the discovery layer to get updated
112+
time.sleep(2)
113+
114+
ingressroute_api = client.resources.get(
115+
api_version="apps.example.com/v1", kind="IngressRoute"
116+
)
117+
118+
# Creating a custom resource (CR) `ingress-route-*`, using the above CRD `ingressroutes.apps.example.com`
119+
120+
ingressroute_manifest_first = {
121+
"apiVersion": "apps.example.com/v1",
122+
"kind": "IngressRoute",
123+
"metadata": {
124+
"name": "ingress-route-first",
125+
},
126+
"spec": {
127+
"virtualhost": {
128+
"fqdn": "www.google.com",
129+
"tls": {"secretName": "google-tls"},
130+
},
131+
"strategy": "RoundRobin",
132+
},
133+
}
134+
135+
ingressroute_manifest_second = {
136+
"apiVersion": "apps.example.com/v1",
137+
"kind": "IngressRoute",
138+
"metadata": {
139+
"name": "ingress-route-second",
140+
},
141+
"spec": {
142+
"virtualhost": {
143+
"fqdn": "www.yahoo.com",
144+
"tls": {"secretName": "yahoo-tls"},
145+
},
146+
"strategy": "RoundRobin",
147+
},
148+
}
149+
150+
ingressroute_api.create(body=ingressroute_manifest_first)
151+
ingressroute_api.create(body=ingressroute_manifest_second)
152+
print("\n[INFO] custom resources `ingress-route-*` created\n")
153+
154+
# Listing the `ingress-route-*` custom resources
155+
156+
ingress_routes_list = ingressroute_api.get()
157+
print("%s\t\t\t%s\t\t%s\t\t\t\t%s" % ("NAME", "FQDN", "TLS", "STRATEGY"))
158+
for item in ingress_routes_list.items:
159+
print(
160+
"%s\t%s\t%s\t%s"
161+
% (
162+
item.metadata.name,
163+
item.spec.virtualhost.fqdn,
164+
item.spec.virtualhost.tls,
165+
item.spec.strategy,
166+
)
167+
)
168+
169+
# Patching the ingressroutes custom resources
170+
171+
ingressroute_manifest_first["spec"]["strategy"] = "Random"
172+
ingressroute_manifest_second["spec"]["strategy"] = "WeightedLeastRequest"
173+
174+
patch_ingressroute_first = ingressroute_api.patch(
175+
body=ingressroute_manifest_first, content_type="application/merge-patch+json"
176+
)
177+
patch_ingressroute_second = ingressroute_api.patch(
178+
body=ingressroute_manifest_second, content_type="application/merge-patch+json"
179+
)
180+
181+
print(
182+
"\n[INFO] custom resources `ingress-route-*` patched to update the strategy\n"
183+
)
184+
patched_ingress_routes_list = ingressroute_api.get()
185+
print("%s\t\t\t%s\t\t%s\t\t\t\t%s" % ("NAME", "FQDN", "TLS", "STRATEGY"))
186+
for item in patched_ingress_routes_list.items:
187+
print(
188+
"%s\t%s\t%s\t%s"
189+
% (
190+
item.metadata.name,
191+
item.spec.virtualhost.fqdn,
192+
item.spec.virtualhost.tls,
193+
item.spec.strategy,
194+
)
195+
)
196+
197+
# Deleting the ingressroutes custom resources
198+
199+
delete_ingressroute_first = ingressroute_api.delete(name="ingress-route-first")
200+
delete_ingressroute_second = ingressroute_api.delete(name="ingress-route-second")
201+
202+
print("\n[INFO] custom resources `ingress-route-*` deleted")
203+
204+
# Deleting the ingressroutes.apps.example.com custom resource definition
205+
206+
crd_api.delete(name=name)
207+
print(
208+
"\n[INFO] custom resource definition `ingressroutes.apps.example.com` deleted"
209+
)
210+
211+
212+
if __name__ == "__main__":
213+
main()

examples/dynamic-client/configmap.py

Lines changed: 85 additions & 0 deletions
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)