10
0

Initial commit
All checks were successful
continuous-integration/drone Build is passing

This commit is contained in:
Lauri Võsandi 2022-09-21 12:35:12 +03:00
commit 061916c1d5
4 changed files with 97 additions and 0 deletions

2
.drone.yml Normal file
View File

@ -0,0 +1,2 @@
kind: template
load: docker.yaml

3
Dockerfile Normal file
View File

@ -0,0 +1,3 @@
FROM harbor.k-space.ee/k-space/microservice-base
ADD bind-sidecar.py /
ENTRYPOINT /bind-sidecar.py

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Meta operator
Meta operator allows creating operators without building any binaries

89
bind-sidecar.py Executable file
View File

@ -0,0 +1,89 @@
#!/usr/bin/env python3
import asyncio
import ecs_logging
import logging
import os
import sys
from kubernetes_asyncio.client.api_client import ApiClient
from kubernetes_asyncio import client, config, watch
from time import time
# Get the Logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# Add an ECS formatter to the Handler
handler = logging.StreamHandler()
handler.setFormatter(ecs_logging.StdlibFormatter())
logger.addHandler(handler)
ZONEFILE_TEMPLATE = """
@ IN SOA ns1.%(zone)s. hostmaster.%(zone)s. (2022060820 300 300 300 300)
NS ns1.%(zone)s.
ns1 A %(ip)s
"""
_, ip = sys.argv
PATH_CONFIG = "/var/bind/bind.conf"
PATH_ZONEFILE = "/var/bind/db.%s"
active_zones = set()
def update_config():
with open(PATH_CONFIG + ".part", "w") as fh:
for zone in active_zones:
path = PATH_ZONEFILE % zone
fh.write("zone \"%s\" { type master; file \"%s\"; };\n" % (zone, path))
os.rename(PATH_CONFIG + ".part", PATH_CONFIG)
async def update_loop(v1, apps_api, api_instance, revision):
flt = "codemowers.io", "v1alpha1", "bindzones"
method = api_instance.list_cluster_custom_object
w = watch.Watch()
latest_version = None
logger.info("Subscribing to updates")
async for event in w.stream(method, *flt, resource_version=latest_version):
latest_version = event["object"]["metadata"]["resourceVersion"]
if event["type"] == "ADDED":
zone = event["object"]["metadata"]["name"]
active_zones.add(zone)
path = PATH_ZONEFILE % zone
logger.info("Adding zone: %s", zone)
if not os.path.exists(path):
with open(path + ".part", "w") as fh:
fh.write(ZONEFILE_TEMPLATE % {
"ip": ip,
"zone": zone
})
os.rename(path + ".part", path)
update_config()
elif event["type"] == "DELETED":
logger.info("Removing zone: %s", zone)
active_zones.remove(zone)
os.unlink(PATH_ZONEFILE % event["object"]["metadata"]["name"])
async def main():
if os.getenv("KUBECONFIG"):
await config.load_kube_config()
else:
config.load_incluster_config()
async with ApiClient() as api:
v1 = client.CoreV1Api(api)
apps_api = client.AppsV1Api()
api_instance = client.CustomObjectsApi(api)
revision = str(time())
while True:
try:
await update_loop(v1, apps_api, api_instance, revision)
except asyncio.exceptions.TimeoutError:
pass
if __name__ == "__main__":
loop = asyncio.new_event_loop()
loop.run_until_complete(main())
loop.close()