Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d12a9a5

Browse files
iciclespiderpalnabarun
authored andcommitted
Unittests and example for portforwarding ability added in python-base.
1 parent ae3bce7 commit d12a9a5

File tree

2 files changed

+242
-1
lines changed

2 files changed

+242
-1
lines changed

examples/pod_portforward.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Copyright 2020 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+
Shows the functionality of portforward streaming using an nginx container.
17+
"""
18+
19+
import socket
20+
import time
21+
import urllib.request
22+
23+
from kubernetes import config
24+
from kubernetes.client import Configuration
25+
from kubernetes.client.api import core_v1_api
26+
from kubernetes.client.rest import ApiException
27+
from kubernetes.stream import portforward
28+
29+
30+
def portforward_commands(api_instance):
31+
name = 'portforward-example'
32+
resp = None
33+
try:
34+
resp = api_instance.read_namespaced_pod(name=name,
35+
namespace='default')
36+
except ApiException as e:
37+
if e.status != 404:
38+
print("Unknown error: %s" % e)
39+
exit(1)
40+
41+
if not resp:
42+
print("Pod %s does not exist. Creating it..." % name)
43+
pod_manifest = {
44+
'apiVersion': 'v1',
45+
'kind': 'Pod',
46+
'metadata': {
47+
'name': name
48+
},
49+
'spec': {
50+
'containers': [{
51+
'image': 'nginx',
52+
'name': 'nginx',
53+
}]
54+
}
55+
}
56+
resp = api_instance.create_namespaced_pod(body=pod_manifest,
57+
namespace='default')
58+
while True:
59+
resp = api_instance.read_namespaced_pod(name=name,
60+
namespace='default')
61+
if resp.status.phase != 'Pending':
62+
break
63+
time.sleep(1)
64+
print("Done.")
65+
66+
pf = portforward(api_instance.connect_get_namespaced_pod_portforward,
67+
name, 'default',
68+
ports='80,8080:80')
69+
for port in (80, 8080):
70+
http = pf.socket(port)
71+
http.settimeout(1)
72+
http.sendall(b'GET / HTTP/1.1\r\n')
73+
http.sendall(b'Host: 127.0.0.1\r\n')
74+
http.sendall(b'Accept: */*\r\n')
75+
http.sendall(b'\r\n')
76+
response = b''
77+
while True:
78+
try:
79+
response += http.recv(1024)
80+
except socket.timeout:
81+
break
82+
print(response.decode('utf-8'))
83+
http.close()
84+
85+
# Monkey patch socket.create_connection which is used by http.client and
86+
# urllib.request. The same can be done with urllib3.util.connection.create_connection
87+
# if the "requests" package is used.
88+
def kubernetes_create_connection(address, *args, **kwargs):
89+
dns_name = address[0]
90+
if isinstance(dns_name, bytes):
91+
dns_name = dns_name.decode()
92+
# Look for "<pod-name>.<namspace>.kubernetes" dns names and if found
93+
# provide a socket that is port forwarded to the kuberntest pod.
94+
dns_name = dns_name.split(".")
95+
if len(dns_name) != 3 or dns_name[2] != "kubernetes":
96+
return socket_create_connection(address, *args, **kwargs)
97+
pf = portforward(api_instance.connect_get_namespaced_pod_portforward,
98+
dns_name[0], dns_name[1], ports=str(address[1]))
99+
return pf.socket(address[1])
100+
101+
socket_create_connection = socket.create_connection
102+
socket.create_connection = kubernetes_create_connection
103+
104+
# Access the nginx http server using the "<pod-name>.<namespace>.kubernetes" dns name.
105+
response = urllib.request.urlopen('http://%s.default.kubernetes' % name)
106+
html = response.read().decode('utf-8')
107+
response.close()
108+
print('Status:', response.status)
109+
print(html)
110+
111+
112+
def main():
113+
config.load_kube_config()
114+
c = Configuration()
115+
c.assert_hostname = False
116+
#Configuration.set_default(c)
117+
core_v1 = core_v1_api.CoreV1Api()
118+
119+
portforward_commands(core_v1)
120+
121+
122+
if __name__ == '__main__':
123+
main()

kubernetes/e2e_test/test_client.py

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@
1313
# under the License.
1414

1515
import json
16+
import socket
1617
import time
1718
import unittest
19+
import urllib.request
1820
import uuid
1921

2022
from kubernetes.client import api_client
2123
from kubernetes.client.api import core_v1_api
2224
from kubernetes.e2e_test import base
23-
from kubernetes.stream import stream
25+
from kubernetes.stream import stream, portforward
2426
from kubernetes.stream.ws_client import ERROR_CHANNEL
2527

2628

@@ -119,6 +121,7 @@ def test_pod_apis(self):
119121

120122
resp = api.delete_namespaced_pod(name=name, body={},
121123
namespace='default')
124+
122125
def test_exit_code(self):
123126
client = api_client.ApiClient(configuration=self.config)
124127
api = core_v1_api.CoreV1Api(client)
@@ -159,6 +162,121 @@ def test_exit_code(self):
159162
resp = api.delete_namespaced_pod(name=name, body={},
160163
namespace='default')
161164

165+
def test_portforward_raw(self):
166+
client = api_client.ApiClient(configuration=self.config)
167+
api = core_v1_api.CoreV1Api(client)
168+
169+
name = 'portforward-raw-' + short_uuid()
170+
pod_manifest = manifest_with_command(name, "while true;do nc -l -p 1234 -e /bin/cat; done")
171+
resp = api.create_namespaced_pod(body=pod_manifest,
172+
namespace='default')
173+
self.assertEqual(name, resp.metadata.name)
174+
self.assertTrue(resp.status.phase)
175+
176+
while True:
177+
resp = api.read_namespaced_pod(name=name,
178+
namespace='default')
179+
self.assertEqual(name, resp.metadata.name)
180+
self.assertTrue(resp.status.phase)
181+
if resp.status.phase != 'Pending':
182+
break
183+
time.sleep(1)
184+
185+
pf1234 = portforward(api.connect_get_namespaced_pod_portforward,
186+
name, 'default',
187+
ports='1234')
188+
sock1234 = pf1234.socket(1234)
189+
sock1234.settimeout(1)
190+
sent1234 = b'Test port 1234 forwarding...'
191+
sock1234.sendall(sent1234)
192+
reply1234 = b''
193+
while True:
194+
try:
195+
reply1234 += sock1234.recv(1024)
196+
except socket.timeout:
197+
break
198+
sock1234.close()
199+
self.assertEqual(reply1234, sent1234)
200+
self.assertIsNone(pf1234.error(1234))
201+
202+
pf9999 = portforward(api.connect_get_namespaced_pod_portforward,
203+
name, 'default',
204+
ports='9999:1234')
205+
sock9999 = pf9999.socket(9999)
206+
sock9999.settimeout(1)
207+
sent9999 = b'Test port 9999 forwarding...'
208+
sock9999.sendall(sent9999)
209+
reply9999 = b''
210+
while True:
211+
try:
212+
reply9999 += sock9999.recv(1024)
213+
except socket.timeout:
214+
break
215+
self.assertEqual(reply9999, sent9999)
216+
sock9999.close()
217+
self.assertIsNone(pf9999.error(9999))
218+
219+
resp = api.delete_namespaced_pod(name=name, body={},
220+
namespace='default')
221+
222+
def test_portforward_http(self):
223+
client = api_client.ApiClient(configuration=self.config)
224+
api = core_v1_api.CoreV1Api(client)
225+
226+
name = 'portforward-http-' + short_uuid()
227+
pod_manifest = {
228+
'apiVersion': 'v1',
229+
'kind': 'Pod',
230+
'metadata': {
231+
'name': name
232+
},
233+
'spec': {
234+
'containers': [{
235+
'name': 'nginx',
236+
'image': 'nginx',
237+
}]
238+
}
239+
}
240+
241+
resp = api.create_namespaced_pod(body=pod_manifest,
242+
namespace='default')
243+
self.assertEqual(name, resp.metadata.name)
244+
self.assertTrue(resp.status.phase)
245+
246+
while True:
247+
resp = api.read_namespaced_pod(name=name,
248+
namespace='default')
249+
self.assertEqual(name, resp.metadata.name)
250+
self.assertTrue(resp.status.phase)
251+
if resp.status.phase != 'Pending':
252+
break
253+
time.sleep(1)
254+
255+
def kubernetes_create_connection(address, *args, **kwargs):
256+
dns_name = address[0]
257+
if isinstance(dns_name, bytes):
258+
dns_name = dns_name.decode()
259+
dns_name = dns_name.split(".")
260+
if len(dns_name) != 3 or dns_name[2] != "kubernetes":
261+
return socket_create_connection(address, *args, **kwargs)
262+
pf = portforward(api.connect_get_namespaced_pod_portforward,
263+
dns_name[0], dns_name[1], ports=str(address[1]))
264+
return pf.socket(address[1])
265+
266+
socket_create_connection = socket.create_connection
267+
try:
268+
socket.create_connection = kubernetes_create_connection
269+
response = urllib.request.urlopen('http://%s.default.kubernetes/' % name)
270+
html = response.read().decode('utf-8')
271+
finally:
272+
socket.create_connection = socket_create_connection
273+
274+
self.assertEqual(response.status, 200)
275+
self.assertTrue('<h1>Welcome to nginx!</h1>' in html)
276+
277+
resp = api.delete_namespaced_pod(name=name, body={},
278+
namespace='default')
279+
162280
def test_service_apis(self):
163281
client = api_client.ApiClient(configuration=self.config)
164282
api = core_v1_api.CoreV1Api(client)

0 commit comments

Comments
 (0)