Commit 9917c484 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Add --dry-run and --nginx-directory opts to port-proxy

parent 7ac8dfe4
Loading
Loading
Loading
Loading
+51 −20
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ import pathlib
import signal
import socket
import subprocess
import tempfile
from urllib import parse
from typing import Iterable, Set, TextIO, Union

@@ -27,6 +28,15 @@ IPAddress = Union[ipaddress.IPv4Address, ipaddress.IPv6Address]
logger = logging.getLogger(__name__)


class TemporaryDirectory(tempfile.TemporaryDirectory):

	def __enter__(self):
		return pathlib.Path(self.name)

	def __str__(self):
		return self.name


class StreamConfig:
	"""
	Manage an Nginx stream configuration
@@ -54,14 +64,18 @@ class StreamConfig:
			self.path.unlink()


def add_core_config(engine, opts, nginx_dir=NGINX_BASE):
@contextlib.contextmanager
def add_core_config(engine, opts):
	"""
	Add a minimal Nginx configuration
	"""
	template = engine.get_template('nginx.conf')
	path = pathlib.Path(nginx_dir).joinpath('nginx.conf')
	with path.open('w') as conf:
	with opts.nginx_directory as _dir:
		path = pathlib.Path(_dir)
		with path.joinpath('nginx.conf').open('w') as conf:
			conf.writelines(template.stream(**opts.__dict__))
		path.joinpath('streams').mkdir(exist_ok=True)
		yield path


def parse_cmdline(argv=None):
@@ -76,6 +90,13 @@ def parse_cmdline(argv=None):
	parser.add_argument('--key',
		type=pathlib.Path,
	)
	parser.add_argument('--nginx-directory',
		type=pathlib.Path,
		default=pathlib.Path(NGINX_BASE),
	)
	parser.add_argument('--dry-run',
		action='store_true',
	)

	mutex = parser.add_mutually_exclusive_group()
	mutex.add_argument('--verbose', '-v',
@@ -99,6 +120,9 @@ def parse_cmdline(argv=None):
	elif opts.cert or opts.key:
		parser.error("--cert and --key are not valid for {opts.monitor_url!r}")

	if opts.dry_run:
		opts.nginx_directory = TemporaryDirectory()

	# Set verbosity
	logging.root.setLevel(
		logging.DEBUG   if opts.verbose >= 1 else
@@ -153,19 +177,8 @@ def main(argv=None):
	)
	env.filters['nginx_addr'] = nginx_addr_format

	# Minimal starting config
	add_core_config(env, opts)
	subprocess.check_call(['nginx', '-vt'])
	logger.info("generated minimal nginx configuration")

	# Begin monitoring k8s API for NodePort services
	cmd = ['kubectl', 'get',  'services', '--all-namespaces',
			'--watch', '--output', 'json']
	proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, text=True)
	logger.info("pid %s: kubectl", proc.pid)

	with contextlib.ExitStack() as stack:
		stack.enter_context(proc)
		if not opts.dry_run:
			stack.callback(os.kill, os.getpid(), signal.SIGTERM)

		@stack.push
@@ -174,7 +187,24 @@ def main(argv=None):
				logger.exception("")
				return True

		if os.fork():
		# Minimal starting config
		nginx_dir = stack.enter_context(add_core_config(env, opts))
		try:
			subprocess.check_call(['nginx', '-vt'])
		except FileNotFoundError:
			logger.warning(
					"no nginx binary found, not checking configuration files")
		logger.info("generated minimal nginx configuration in %s", nginx_dir)

		# Begin monitoring k8s API for NodePort services
		cmd = ['kubectl', 'get',  'services', '--all-namespaces',
				'--watch', '--output', 'json']
		proc = stack.enter_context(
			subprocess.Popen(cmd, stdout=subprocess.PIPE, text=True))
		stack.callback(proc.terminate)
		logger.info("pid %s: kubectl", proc.pid)

		if not opts.dry_run and os.fork():
			# Parent becomes nginx
			logger.info("pid %s: nginx", os.getpid())
			os.execvp('nginx', ['nginx'])
@@ -185,12 +215,13 @@ def main(argv=None):
		for uid, stream in filter_services(proc.stdout):
			if not uid:
				logging.info("reloading nginx")
				if not opts.dry_run:
					subprocess.check_call(['nginx', '-s', 'reload'])
				continue

			streams = streams_map[uid]
			if stream:
				stream.enable(env)
				stream.enable(env, nginx_base=nginx_dir)
				streams.append(stream)
				logging.info("stream added: %s", stream.name)
			else:
+2 −2
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ error_log /dev/stderr {{
	'warn'
}};

include /etc/nginx/modules-enabled/*.conf;
include {{ nginx_directory }}/modules-enabled/*.conf;

events {
	worker_connections 768;
@@ -40,5 +40,5 @@ http {
}

stream {
	include /etc/nginx/streams/*.conf;
	include {{ nginx_directory }}/streams/*.conf;
}