36 lines
1.3 KiB
Python
Executable File
36 lines
1.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# "Have-A-Port" | ephemeral port picker for LoadBalancer-type Kubernetes services in clusters with a single-address external address pool
|
|
from kubernetes import client, config
|
|
import sys, random
|
|
|
|
SVC_TYPE = 'LoadBalancer'
|
|
|
|
def getopts():
|
|
"""parse command-line"""
|
|
from optparse import OptionParser, OptionValueError
|
|
usage = "%prog [options]"
|
|
parser = OptionParser(usage=usage)
|
|
parser.add_option("-n", "--count", type="int", default=1, dest="port_count", help="number of ports needed (default: %default)")
|
|
return parser.parse_args()
|
|
|
|
options, args = getopts()
|
|
|
|
# load client configuration (kubeconfig)
|
|
config.load_kube_config()
|
|
|
|
# establish API connection
|
|
connection = client.CoreV1Api()
|
|
# query service objects
|
|
all_services = connection.list_service_for_all_namespaces(watch=False)
|
|
|
|
# determine ports in use
|
|
ports_per_svc = [ svc.spec.ports for svc in all_services.items if svc.spec.type == SVC_TYPE]
|
|
used_ports = [svc_port.port for svc_ports in ports_per_svc for svc_port in svc_ports]
|
|
|
|
# determine available ports
|
|
full_port_range = range(49152, 65536) # https://tools.ietf.org/html/rfc6335#section-8.1.2
|
|
available_ports = list(set(full_port_range) - set(used_ports))
|
|
|
|
# pick available ports
|
|
print(' '.join(map(str, random.sample(available_ports, options.port_count))))
|