|
13 | 13 | # under the License.
|
14 | 14 |
|
15 | 15 | import json
|
| 16 | +import socket |
16 | 17 | import time
|
17 | 18 | import unittest
|
| 19 | +import urllib.request |
18 | 20 | import uuid
|
19 | 21 |
|
20 | 22 | from kubernetes.client import api_client
|
21 | 23 | from kubernetes.client.api import core_v1_api
|
22 | 24 | from kubernetes.e2e_test import base
|
23 |
| -from kubernetes.stream import stream |
| 25 | +from kubernetes.stream import stream, portforward |
24 | 26 | from kubernetes.stream.ws_client import ERROR_CHANNEL
|
25 | 27 |
|
26 | 28 |
|
@@ -119,6 +121,7 @@ def test_pod_apis(self):
|
119 | 121 |
|
120 | 122 | resp = api.delete_namespaced_pod(name=name, body={},
|
121 | 123 | namespace='default')
|
| 124 | + |
122 | 125 | def test_exit_code(self):
|
123 | 126 | client = api_client.ApiClient(configuration=self.config)
|
124 | 127 | api = core_v1_api.CoreV1Api(client)
|
@@ -159,6 +162,104 @@ def test_exit_code(self):
|
159 | 162 | resp = api.delete_namespaced_pod(name=name, body={},
|
160 | 163 | namespace='default')
|
161 | 164 |
|
| 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 | + pf = portforward(api.connect_get_namespaced_pod_portforward, |
| 186 | + name, 'default', |
| 187 | + ports='1234') |
| 188 | + sock = pf.socket(1234) |
| 189 | + sock.settimeout(1) |
| 190 | + sent = b'Test port forwarding...' |
| 191 | + sock.sendall(sent) |
| 192 | + reply = b'' |
| 193 | + while True: |
| 194 | + try: |
| 195 | + reply += sock.recv(1024) |
| 196 | + except socket.timeout: |
| 197 | + break |
| 198 | + self.assertEqual(sent, reply) |
| 199 | + sock.close() |
| 200 | + self.assertIsNone(pf.error(1234)) |
| 201 | + |
| 202 | + resp = api.delete_namespaced_pod(name=name, body={}, |
| 203 | + namespace='default') |
| 204 | + |
| 205 | + def test_portforward_http(self): |
| 206 | + client = api_client.ApiClient(configuration=self.config) |
| 207 | + api = core_v1_api.CoreV1Api(client) |
| 208 | + |
| 209 | + name = 'portforward-http-' + short_uuid() |
| 210 | + pod_manifest = { |
| 211 | + 'apiVersion': 'v1', |
| 212 | + 'kind': 'Pod', |
| 213 | + 'metadata': { |
| 214 | + 'name': name |
| 215 | + }, |
| 216 | + 'spec': { |
| 217 | + 'containers': [{ |
| 218 | + 'name': 'nginx', |
| 219 | + 'image': 'nginx', |
| 220 | + }] |
| 221 | + } |
| 222 | + } |
| 223 | + |
| 224 | + resp = api.create_namespaced_pod(body=pod_manifest, |
| 225 | + namespace='default') |
| 226 | + self.assertEqual(name, resp.metadata.name) |
| 227 | + self.assertTrue(resp.status.phase) |
| 228 | + |
| 229 | + while True: |
| 230 | + resp = api.read_namespaced_pod(name=name, |
| 231 | + namespace='default') |
| 232 | + self.assertEqual(name, resp.metadata.name) |
| 233 | + self.assertTrue(resp.status.phase) |
| 234 | + if resp.status.phase != 'Pending': |
| 235 | + break |
| 236 | + time.sleep(1) |
| 237 | + |
| 238 | + def kubernetes_create_connection(address, *args, **kwargs): |
| 239 | + dns_name = address[0] |
| 240 | + if isinstance(dns_name, bytes): |
| 241 | + dns_name = dns_name.decode() |
| 242 | + dns_name = dns_name.split(".") |
| 243 | + if len(dns_name) != 3 or dns_name[2] != "kubernetes": |
| 244 | + return socket_create_connection(address, *args, **kwargs) |
| 245 | + pf = portforward(api.connect_get_namespaced_pod_portforward, |
| 246 | + dns_name[0], dns_name[1], ports=str(address[1])) |
| 247 | + return pf.socket(address[1]) |
| 248 | + |
| 249 | + socket_create_connection = socket.create_connection |
| 250 | + try: |
| 251 | + socket.create_connection = kubernetes_create_connection |
| 252 | + response = urllib.request.urlopen('http://%s.default.kubernetes/' % name) |
| 253 | + html = response.read().decode('utf-8') |
| 254 | + finally: |
| 255 | + socket.create_connection = socket_create_connection |
| 256 | + |
| 257 | + self.assertEqual(response.status, 200) |
| 258 | + self.assertTrue('<h1>Welcome to nginx!</h1>' in html) |
| 259 | + |
| 260 | + resp = api.delete_namespaced_pod(name=name, body={}, |
| 261 | + namespace='default') |
| 262 | + |
162 | 263 | def test_service_apis(self):
|
163 | 264 | client = api_client.ApiClient(configuration=self.config)
|
164 | 265 | api = core_v1_api.CoreV1Api(client)
|
|
0 commit comments