Fetches used external ports in order to guarantee no collisions.

This commit is contained in:
benbierens 2023-11-14 10:49:14 +01:00
parent 4192952a37
commit b47b596062
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
4 changed files with 52 additions and 6 deletions

View File

@ -84,6 +84,31 @@ namespace KubernetesWorkflow
return result;
}
public int[] GetUsedExternalPorts()
{
return client.Run(c =>
{
var result = new List<int>();
var services = c.ListServiceForAllNamespaces();
var nodePorts = services.Items.Where(s => s.Spec.Type == "NodePort").ToArray();
if (!nodePorts.Any()) return result.ToArray();
foreach (var service in nodePorts)
{
foreach (var port in service.Spec.Ports)
{
if (port.NodePort.HasValue)
{
result.Add(port.NodePort.Value);
}
}
}
return result.ToArray();
});
}
public void DeleteAllNamespacesStartingWith(string prefix)
{
log.Debug();

View File

@ -57,7 +57,7 @@ namespace KubernetesWorkflow.Recipe
protected Port AddExposedPort(int number, string tag, PortProtocol protocol = PortProtocol.TCP)
{
return AddExposedPort(factory.CreatePort(number, tag, protocol));
return AddExposedPort(factory.CreateExternalPort(number, tag, protocol));
}
protected Port AddInternalPort(string tag = "", PortProtocol protocol = PortProtocol.TCP)

View File

@ -5,12 +5,13 @@ namespace KubernetesWorkflow.Recipe
{
public class RecipeComponentFactory
{
private NumberSource internalNumberSource = new NumberSource(8080);
private static NumberSource externalNumberSource = new NumberSource(30000);
private readonly NumberSource internalNumberSource = new NumberSource(8080);
private static readonly NumberSource externalNumberSource = new NumberSource(30000);
private static int[] usedExternalPorts = Array.Empty<int>();
public Port CreatePort(int number, string tag, PortProtocol protocol)
public void Update(K8sController controller)
{
return new Port(number, tag, protocol);
usedExternalPorts = controller.GetUsedExternalPorts();
}
public Port CreateInternalPort(string tag, PortProtocol protocol)
@ -18,9 +19,22 @@ namespace KubernetesWorkflow.Recipe
return new Port(internalNumberSource.GetNextNumber(), tag, protocol);
}
public Port CreateExternalPort(int number, string tag, PortProtocol protocol)
{
if (usedExternalPorts.Contains(number)) throw new Exception($"External port number {number} is already in use by the cluster.");
return new Port(number, tag, protocol);
}
public Port CreateExternalPort(string tag, PortProtocol protocol)
{
return new Port(externalNumberSource.GetNextNumber(), tag, protocol);
while (true)
{
var number = externalNumberSource.GetNextNumber();
if (!usedExternalPorts.Contains(number))
{
return new Port(number, tag, protocol);
}
}
}
public EnvVar CreateEnvVar(string name, int value)

View File

@ -54,12 +54,19 @@ namespace KubernetesWorkflow
{
return K8s(controller =>
{
componentFactory.Update(controller);
var recipes = CreateRecipes(numberOfContainers, recipeFactory, startupConfig);
var startResult = controller.BringOnline(recipes, location);
var containers = CreateContainers(startResult, recipes, startupConfig);
var rc = new RunningContainers(startupConfig, startResult, containers);
cluster.Configuration.Hooks.OnContainersStarted(rc);
if (startResult.ExternalService != null)
{
componentFactory.Update(controller);
}
return rc;
});
}