2018-10-23 18:29:33 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
## run the following from a cron to update the haproxy config
|
|
|
|
# python gateway_config.py | sudo tee /etc/haproxy/haproxy.cfg
|
|
|
|
# sudo service haproxy restart
|
|
|
|
|
|
|
|
import os
|
|
|
|
import requests
|
|
|
|
import jinja2
|
|
|
|
|
|
|
|
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
|
|
|
|
|
|
|
|
KUBERNETES_MASTER_PORT = 6443
|
|
|
|
KUBERNETES_MASTER_IP = "10.0.20.7" # update with the private IP of one of the master nodes
|
|
|
|
KUBECTL_HOST = "https://%s:%d" % (KUBERNETES_MASTER_IP, KUBERNETES_MASTER_PORT)
|
|
|
|
KUBECTL_TOKEN = "" # JWT, not base64 encoded. Get this from the serviceaccount secret
|
|
|
|
KUBECTL_VERIFY_SSL = False
|
|
|
|
HAPROXY_CONFIG_TEMPLATE_FILE = "haproxy.j2"
|
|
|
|
|
|
|
|
def get_haproxy_config_template():
|
|
|
|
with open(os.path.join(__location__, HAPROXY_CONFIG_TEMPLATE_FILE), 'r') as myfile:
|
|
|
|
data = myfile.read()
|
|
|
|
return jinja2.Template(data)
|
|
|
|
|
|
|
|
def get_k8s_resources(resource):
|
|
|
|
"""use the k8s API to get node details"""
|
|
|
|
url = "%s/api/v1/%s" % (KUBECTL_HOST, resource)
|
|
|
|
headers = {'user-agent': 'gateway-config', 'Accept': 'application/json', 'Authorization': 'Bearer %s' % KUBECTL_TOKEN}
|
|
|
|
services_request = requests.get(url, headers=headers, verify=KUBECTL_VERIFY_SSL)
|
|
|
|
if services_request.status_code != 200:
|
|
|
|
raise Exception(services_request.content)
|
|
|
|
return services_request.json()['items']
|
|
|
|
|
|
|
|
def get_endpoints_for_loadbalancers():
|
|
|
|
load_balanced_endpoints = []
|
|
|
|
services = get_k8s_resources('services')
|
|
|
|
endpoints = get_k8s_resources('endpoints')
|
|
|
|
for service in services:
|
|
|
|
for endpoint in endpoints:
|
|
|
|
if (service['metadata']['name'] == endpoint['metadata']['name']
|
|
|
|
and service['metadata']['namespace'] == endpoint['metadata']['namespace']
|
|
|
|
and service['spec']['type'] == 'LoadBalancer'):
|
|
|
|
if endpoint['subsets']:
|
|
|
|
for subset in endpoint['subsets']:
|
|
|
|
for port in service['spec']['ports']:
|
2024-12-21 13:26:53 +01:00
|
|
|
if port['port'] in [80, 443] and 'ingress' not in service['metadata']['name']:
|
2018-10-23 18:29:33 +02:00
|
|
|
continue
|
|
|
|
gateway_endpoint = {}
|
2024-12-21 13:26:53 +01:00
|
|
|
service_name = service['metadata']['name'].replace(" ", "-")
|
|
|
|
gateway_endpoint['name'] = "SRV_%s" % (service_name)
|
|
|
|
gateway_endpoint['port'] = "%d" % (port['port'])
|
|
|
|
gateway_endpoint['labels'] = "%s" % (service['metadata']['labels'])
|
2018-10-23 18:29:33 +02:00
|
|
|
gateway_endpoint['mode'] = "%s" % port['protocol'].lower()
|
|
|
|
gateway_endpoint['balance'] = 'leastconn'
|
|
|
|
gateway_endpoint['servers'] = []
|
2024-12-21 19:18:32 +01:00
|
|
|
server_number = 1
|
2018-10-23 18:29:33 +02:00
|
|
|
if 'addresses' in subset:
|
|
|
|
for address in subset['addresses']:
|
2024-12-21 19:40:02 +01:00
|
|
|
gateway_endpoint['servers'].append("server %s_%s %s:%d cookie %s" % (service_name, server_number, address['ip'], port['targetPort']), server_number)
|
2018-10-23 18:29:33 +02:00
|
|
|
server_number += 1
|
|
|
|
load_balanced_endpoints.append(gateway_endpoint)
|
|
|
|
return load_balanced_endpoints
|
|
|
|
|
|
|
|
def get_haproxy_config():
|
|
|
|
load_balanced_endpoints = get_endpoints_for_loadbalancers()
|
2024-12-21 19:18:32 +01:00
|
|
|
haproxy_config = get_haproxy_config_template().render(backends=load_balanced_endpoints)
|
2018-10-23 18:29:33 +02:00
|
|
|
return haproxy_config
|
|
|
|
|
|
|
|
def main():
|
|
|
|
print(get_haproxy_config())
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|