From f7f269d685c23727977035e9f216d75b7fe9a031 Mon Sep 17 00:00:00 2001 From: Matthew Baggett <matthew@baggett.me> Date: Wed, 26 Jun 2024 12:54:49 +0200 Subject: [PATCH] Fix bugs with loadbalancer --- src/Bouncer.php | 54 ++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/Bouncer.php b/src/Bouncer.php index 0a21e94..d573234 100644 --- a/src/Bouncer.php +++ b/src/Bouncer.php @@ -211,7 +211,7 @@ class Bouncer } // If BOUNCER_IGNORE is set, skip this service. if (isset($envs['BOUNCER_IGNORE'])) { - $this->logger->warning('Container {container_name} has BOUNCER_IGNORE set, skipping.', ['emoji' => Emoji::warning() . ' Bouncer.php', 'container_name' => $container['Name']]); + $this->logger->warning('Container {container_name} has BOUNCER_IGNORE set, skipping.', ['emoji' => Emoji::warning() . ' ', 'container_name' => $container['Name']]); continue; } @@ -276,7 +276,7 @@ class Bouncer $services = json_decode($this->docker->request('GET', 'services')->getBody()->getContents(), true); if (isset($services['message'])) { - $this->logger->debug('Something happened while interrogating services.. This node is not a swarm node, cannot have services: {message}', ['emoji' => Emoji::warning() . ' Bouncer.php', 'message' => $services['message']]); + $this->logger->debug('Something happened while interrogating services.. This node is not a swarm node, cannot have services: {message}', ['emoji' => Emoji::warning() . ' ', 'message' => $services['message']]); } else { foreach ($services as $service) { $envs = []; @@ -288,6 +288,7 @@ class Bouncer ) { continue; } + // Parse all the environment variables and store them in an array. foreach ($service['Spec']['TaskTemplate']['ContainerSpec']['Env'] as $env) { [$envKey, $envVal] = explode('=', $env, 2); @@ -295,16 +296,17 @@ class Bouncer $envs[$envKey] = $envVal; } } - \Kint::dump($service['Spec']['TaskTemplate']['ContainerSpec']['Env']); ksort($envs); + // If there are no BOUNCER_* environment variables, skip this service. if (count($envs) == 0) { - $this->logger->debug('Service {service_name} has no BOUNCER_* environment variables, skipping.', ['emoji' => Emoji::warning() . ' Bouncer.php', 'service_name' => $service['Spec']['Name']]); + $this->logger->debug('Service {service_name} has no BOUNCER_* envs set, skipping.', ['emoji' => Emoji::ghost() . ' ', 'service_name' => $service['Spec']['Name']]); continue; } + // if BOUNCER_IGNORE is set, skip this service. if (isset($envs['BOUNCER_IGNORE'])) { - $this->logger->warning('Service {service_name} has BOUNCER_IGNORE set, skipping.', ['emoji' => Emoji::warning() . ' Bouncer.php', 'service_name' => $service['Spec']['Name']]); + $this->logger->debug('Service {service_name} has BOUNCER_IGNORE set, skipping.', ['emoji' => Emoji::warning() . ' ', 'service_name' => $service['Spec']['Name']]); continue; } @@ -333,7 +335,7 @@ class Bouncer $bouncerTarget->setEndpoints(['172.17.0.1']); $bouncerTarget->setPort(intval($service['Endpoint']['Ports'][0]['PublishedPort'])); } else { - $this->logger->warning('{label}: ports block missing for {target_name}. Try setting BOUNCER_TARGET_PORT.', ['emoji' => Emoji::warning() . ' Bouncer.php', 'label' => $bouncerTarget->getLabel(), 'target_name' => $bouncerTarget->getName()]); + $this->logger->warning('{label}: ports block missing for {target_name}. Try setting BOUNCER_TARGET_PORT.', ['emoji' => Emoji::warning() . ' ', 'label' => $bouncerTarget->getLabel(), 'target_name' => $bouncerTarget->getName()]); \Kint::dump( $bouncerTarget->getId(), $bouncerTarget->getLabel(), @@ -352,6 +354,10 @@ class Bouncer unset($bouncerTarget); } } + + if(isset($bouncerTarget)) { + $bouncerTargets[] = $bouncerTarget; + } } } } @@ -372,15 +378,16 @@ class Bouncer ); } } + $this->logger->debug("There are {count} bouncer targets, of which {validCount} are valid", ['count' => count($bouncerTargets), 'validCount' => count($validBouncerTargets)]); - $this->logger->warning('Interrogating SERVICES for BOUNCER_* environment variables found {count} containers.', ['emoji' => Emoji::magnifyingGlassTiltedLeft(), 'count' => count($validBouncerTargets)]); + $this->logger->warning('Interrogating SERVICES for BOUNCER_* environment variables found {count} services.', ['emoji' => Emoji::magnifyingGlassTiltedLeft(), 'count' => count($validBouncerTargets)]); return $validBouncerTargets; } public function run(): void { - $this->logger->info('Starting Bouncer. Built {build_id} on {build_date}, {build_ago}', ['emoji' => Emoji::redHeart() . ' Bouncer.php', 'build_id' => $this->settings->get('build/id'), 'build_date' => $this->settings->get('build/date')->toDateTimeString(), 'build_ago' => $this->settings->get('build/date')->ago()]); + $this->logger->info('Starting Bouncer. Built {build_id} on {build_date}, {build_ago}', ['emoji' => Emoji::redHeart() . ' ', 'build_id' => $this->settings->get('build/id'), 'build_date' => $this->settings->get('build/date')->toDateTimeString(), 'build_ago' => $this->settings->get('build/date')->ago()]); $this->logger->info('Build #{git_sha}: "{build_message}"', ['emoji' => Emoji::memo(), 'git_sha' => $this->settings->get('build/sha_short'), 'build_message' => $this->settings->get('build/message')]); $this->logger->debug(' > HTTPS Listener is on {https_port}', ['emoji' => Emoji::ship(), 'https_port' => $this->settings->get('bouncer/https_port')]); $this->logger->debug(' > HTTP Listener is on {http_port}', ['emoji' => Emoji::ship(), 'http_port' => $this->settings->get('bouncer/http_port')]); @@ -596,7 +603,7 @@ class Bouncer $containerStateDiff = $this->diff($this->previousContainerState, $newContainerState); if (!$isTainted && !empty($containerStateDiff)) { if ($this->settings->if('logger/show_state_deltas')) { - $this->logger->warning('Container state has changed', ['emoji' => Emoji::warning() . ' Bouncer.php']); + $this->logger->warning('Container state has changed', ['emoji' => Emoji::warning() . ' ']); echo $containerStateDiff; } $isTainted = true; @@ -608,7 +615,7 @@ class Bouncer if ($this->isSwarmMode()) { $services = json_decode($this->docker->request('GET', 'services')->getBody()->getContents(), true); if (isset($services['message'])) { - $this->logger->warning('Something happened while interrogating services.. This node is not a swarm node, cannot have services: {message}', ['emoji' => Emoji::warning() . ' Bouncer.php', 'message' => $services['message']]); + $this->logger->warning('Something happened while interrogating services.. This node is not a swarm node, cannot have services: {message}', ['emoji' => Emoji::warning() . ' ', 'message' => $services['message']]); } else { foreach ($services as $service) { $name = $service['Spec']['Name']; @@ -636,7 +643,7 @@ class Bouncer $swarmStateDiff = $this->diff($this->previousSwarmState, $newSwarmState); if ($this->isSwarmMode() && !$isTainted && !empty($swarmStateDiff)) { if ($this->settings->if('logger/show_state_deltas')) { - $this->logger->warning('Swarm state has changed', ['emoji' => Emoji::warning() . ' Bouncer.php']); + $this->logger->warning('Swarm state has changed', ['emoji' => Emoji::warning() . ' ']); echo $swarmStateDiff; } $isTainted = true; @@ -672,7 +679,7 @@ class Bouncer } catch (ServerException $exception) { $this->setSwarmMode(false); } catch (ConnectException $exception) { - $this->logger->critical('Unable to connect to docker socket!', ['emoji' => Emoji::warning() . ' Bouncer.php']); + $this->logger->critical('Unable to connect to docker socket!', ['emoji' => Emoji::warning() . ' ']); $this->logger->critical($exception->getMessage()); exit(1); @@ -690,9 +697,6 @@ class Bouncer foreach($targets as $target){ $this->logger->info('Found target {target}', ['emoji' => Emoji::magnifyingGlassTiltedLeft(), 'target' => $target->getName()]); - \Kint::dump( - $target->getDomains(), - ); } // Use some bs to sort the targets by domain from right to left. @@ -720,7 +724,7 @@ class Bouncer } if ($this->isTestMode()) { - $this->logger->info('Test mode enabled, not restarting nginx. Infact, I\'ll die now..', ['emoji' => Emoji::warning() . ' Bouncer.php']); + $this->logger->info('Test mode enabled, not restarting nginx. Infact, I\'ll die now..', ['emoji' => Emoji::warning() . ' ']); $this->dumpConfigs(); exit(0); @@ -836,15 +840,15 @@ class Bouncer 'file' => $target->getNginxConfigFileName(), 'config_dir' => Bouncer::FILESYSTEM_CONFIG_DIR, ]; - $this->logger->info('Created {label}', $context + ['emoji' => Emoji::pencil() . ' Bouncer.php']); - $this->logger->debug(' -> {config_dir}/{file}', $context + ['emoji' => Emoji::pencil() . ' Bouncer.php']); - $this->logger->debug(' -> {domain}', $context + ['emoji' => Emoji::pencil() . ' Bouncer.php']); + $this->logger->info('Created {label}', $context + ['emoji' => Emoji::pencil() . ' ']); + $this->logger->debug(' -> {config_dir}/{file}', $context + ['emoji' => Emoji::pencil() . ' ']); + $this->logger->debug(' -> {domain}', $context + ['emoji' => Emoji::pencil() . ' ']); $this->logger->critical('{label} cert type is {cert_type}', $context + ['emoji' => Emoji::catFace(), 'cert_type' => $target->getTypeCertInUse()->name]); } } else { - $this->logger->info('More than {num_max} Nginx configs generated.. Too many to show them all!', ['emoji' => Emoji::pencil() . ' Bouncer.php', 'num_max' => $this->getMaximumNginxConfigCreationNotices()]); + $this->logger->info('More than {num_max} Nginx configs generated.. Too many to show them all!', ['emoji' => Emoji::pencil() . ' ', 'num_max' => $this->getMaximumNginxConfigCreationNotices()]); } - $this->logger->info('Updated {num_created} Nginx configs, {num_changed} changed..', ['emoji' => Emoji::pencil() . ' Bouncer.php', 'num_created' => count($targets), 'num_changed' => count($changedTargets)]); + $this->logger->info('Updated {num_created} Nginx configs, {num_changed} changed..', ['emoji' => Emoji::pencil() . ' ', 'num_created' => count($targets), 'num_changed' => count($changedTargets)]); $this->pruneNonExistentConfigs($targets); } @@ -967,13 +971,13 @@ class Bouncer $command->addFlag('n'); $command->addFlag('m', $this->environment['BOUNCER_LETSENCRYPT_EMAIL']); $command->addArgument('agree-tos'); - $this->logger->info('Generating letsencrypt for {target_name} - {command}', ['emoji' => Emoji::pencil() . ' Bouncer.php', 'target_name' => $target->getName(), 'command' => $command->__toString()]); + $this->logger->info('Generating letsencrypt for {target_name} - {command}', ['emoji' => Emoji::pencil() . ' ', 'target_name' => $target->getName(), 'command' => $command->__toString()]); $shell->run($command); if ($shell->getReturnValue() == 0) { $this->logger->info('Generating successful', ['emoji' => Emoji::partyPopper()]); } else { - $this->logger->critical('Generating failed!', ['emoji' => Emoji::warning() . ' Bouncer.php']); + $this->logger->critical('Generating failed!', ['emoji' => Emoji::warning() . ' ']); } // Re-enable nginx tweaks @@ -995,7 +999,7 @@ class Bouncer $shell = new Exec(); $command = new CommandBuilder('/usr/sbin/nginx'); $command->addFlag('s', 'reload'); - $this->logger->info('Restarting nginx', ['emoji' => Emoji::timerClock() . ' Bouncer.php']); + $this->logger->info('Restarting nginx', ['emoji' => Emoji::timerClock() . ' ']); $nginxRestartOutput = $shell->run($command); $this->logger->debug('Nginx restarted {restart_output}', ['restart_output' => $nginxRestartOutput, 'emoji' => Emoji::partyPopper()]); } @@ -1008,7 +1012,7 @@ class Bouncer if ($file['path'] == 'default.conf') { continue; } - $this->logger->info('Dumping {file}', ['emoji' => Emoji::pencil() . ' Bouncer.php', 'file' => $file['path']]); + $this->logger->info('Dumping {file}', ['emoji' => Emoji::pencil() . ' ', 'file' => $file['path']]); echo $this->configFilesystem->read($file['path']); } }