Skip to content

Even(ish) allocation of hosts between endpoints #58

Description

@sol1-matt

Problem: Icinga has a high check load so you've added more endpoints to split the load and now you need to allocate hosts to those endpoints evenly.

The implementation for this used the ip address to create some stickiness for hosts so they wouldn't move around to different zones all the time unless the number of zones changed or the ip address changed.

The below is a custom zoneHelper implementation. It needs a bit of thought to be brought into the native code base.

	// Simple function to convert an IP address to a group number between 1 and $groups
	// This is useful for splitting hosts into zones based on IP address in a static by random way as long as the ip doesn't change
	function ip_to_group(string $ip, int $groups): ?int {
		if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) || $groups <= 0) {
			return null;
		}

		$sum = array_sum(explode('.', $ip));
		return ($sum % $groups) + 1;
	}

	// This is a function that you can use to add complex rules to define 
	// host zones based on netbox data, eg: ip range mapping to zone.
	// While possible using Import modifiers and Sync rule property filters 
	// forking this repo and writing your own function reduces the number require in complex setups.
	private function zoneHelper(array $in) 	{
		$output = array();
		// Implement your custom zone mapping logic here
		$NUMBER_OF_ZONES = 2; // Change this to the number of zones you want to split into
		foreach ($in as $row) {
			$row->deterministic_zone = NULL;	// set the default zone, it gets overwritten if we can find a group from the primary ip info
			// We only try if the there is a primary_ip
			if (property_exists($row,'primary_ip')) {
				if (! is_null($row->primary_ip) and property_exists($row->primary_ip, 'address')) {
					// Extract the address for the primary ip and attempt to determine the zone group
					$zone_group_number = $this->ip_to_group(explode('/', $row->primary_ip->address)[0], $NUMBER_OF_ZONES);
					// Set the zone if we got a valid group number
					if (! is_null($zone_group_number)) {
						$row->deterministic_zone = 'prod' . $zone_group_number;
					}
				}
			} 
		$output = array_merge($output, [(object)$row]);
		}
		return $output;
	}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions