From 8ba4b1a2907fc4661ffc56b8e1613667f3041081 Mon Sep 17 00:00:00 2001 From: benbierens Date: Fri, 2 Jun 2023 11:07:36 +0200 Subject: [PATCH] Removes pre-assigned service ports and reads back service-ports assigned by k8s cluster. --- KubernetesWorkflow/ApplicationLifecycle.cs | 6 --- KubernetesWorkflow/K8sController.cs | 45 +++++++++++++++++----- KubernetesWorkflow/WorkflowCreator.cs | 1 - KubernetesWorkflow/WorkflowNumberSource.cs | 9 +---- 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/KubernetesWorkflow/ApplicationLifecycle.cs b/KubernetesWorkflow/ApplicationLifecycle.cs index 7d6fb3d..b14fe52 100644 --- a/KubernetesWorkflow/ApplicationLifecycle.cs +++ b/KubernetesWorkflow/ApplicationLifecycle.cs @@ -6,7 +6,6 @@ namespace KubernetesWorkflow { private static object instanceLock = new object(); private static ApplicationLifecycle? instance; - private readonly NumberSource servicePortNumberSource = new NumberSource(30001); private readonly NumberSource namespaceNumberSource = new NumberSource(0); private ApplicationLifecycle() @@ -27,11 +26,6 @@ namespace KubernetesWorkflow } } - public NumberSource GetServiceNumberSource() - { - return servicePortNumberSource; - } - public string GetTestNamespace() { return namespaceNumberSource.GetNextNumber().ToString("D5"); diff --git a/KubernetesWorkflow/K8sController.cs b/KubernetesWorkflow/K8sController.cs index 803fea0..e0f8627 100644 --- a/KubernetesWorkflow/K8sController.cs +++ b/KubernetesWorkflow/K8sController.cs @@ -439,7 +439,7 @@ namespace KubernetesWorkflow { var result = new Dictionary(); - var ports = CreateServicePorts(result, containerRecipes); + var ports = CreateServicePorts(containerRecipes); if (!ports.Any()) { @@ -462,9 +462,40 @@ namespace KubernetesWorkflow client.Run(c => c.CreateNamespacedService(serviceSpec, K8sTestNamespace)); + ReadBackServiceAndMapPorts(serviceSpec, containerRecipes, result); + return (serviceSpec.Metadata.Name, result); } + private void ReadBackServiceAndMapPorts(V1Service serviceSpec, ContainerRecipe[] containerRecipes, Dictionary result) + { + // For each container-recipe, we need to figure out which service-ports it was assigned by K8s. + var readback = client.Run(c => c.ReadNamespacedService(serviceSpec.Metadata.Name, K8sTestNamespace)); + foreach (var r in containerRecipes) + { + if (r.ExposedPorts.Any()) + { + var firstExposedPort = r.ExposedPorts.First(); + var portName = GetNameForPort(r, firstExposedPort); + + var matchingServicePorts = readback.Spec.Ports.Where(p => p.Name == portName); + if (matchingServicePorts.Any()) + { + // These service ports belongs to this recipe. + var optionals = matchingServicePorts.Select(p => MapNodePortIfAble(p, portName)); + var ports = optionals.Where(p => p != null).Select(p => p!).ToArray(); + result.Add(r, ports); + } + } + } + } + + private Port? MapNodePortIfAble(V1ServicePort p, string tag) + { + if (p.NodePort == null) return null; + return new Port(p.NodePort.Value, tag); + } + private void DeleteService(string serviceName) { client.Run(c => c.DeleteNamespacedService(serviceName, K8sTestNamespace)); @@ -479,36 +510,30 @@ namespace KubernetesWorkflow }; } - private List CreateServicePorts(Dictionary servicePorts, ContainerRecipe[] recipes) + private List CreateServicePorts(ContainerRecipe[] recipes) { var result = new List(); foreach (var recipe in recipes) { - result.AddRange(CreateServicePorts(servicePorts, recipe)); + result.AddRange(CreateServicePorts(recipe)); } return result; } - private List CreateServicePorts(Dictionary servicePorts, ContainerRecipe recipe) + private List CreateServicePorts(ContainerRecipe recipe) { var result = new List(); - var usedPorts = new List(); foreach (var port in recipe.ExposedPorts) { - var servicePort = workflowNumberSource.GetServicePort(); - usedPorts.Add(new Port(servicePort, "")); - result.Add(new V1ServicePort { Name = GetNameForPort(recipe, port), Protocol = "TCP", Port = port.Number, TargetPort = GetNameForPort(recipe, port), - NodePort = servicePort }); } - servicePorts.Add(recipe, usedPorts.ToArray()); return result; } diff --git a/KubernetesWorkflow/WorkflowCreator.cs b/KubernetesWorkflow/WorkflowCreator.cs index aa0a098..3a707cc 100644 --- a/KubernetesWorkflow/WorkflowCreator.cs +++ b/KubernetesWorkflow/WorkflowCreator.cs @@ -22,7 +22,6 @@ namespace KubernetesWorkflow public StartupWorkflow CreateWorkflow() { var workflowNumberSource = new WorkflowNumberSource(numberSource.GetNextNumber(), - ApplicationLifecycle.Instance.GetServiceNumberSource(), containerNumberSource); return new StartupWorkflow(log, workflowNumberSource, cluster, knownPods, testNamespace); diff --git a/KubernetesWorkflow/WorkflowNumberSource.cs b/KubernetesWorkflow/WorkflowNumberSource.cs index 8cbab34..cf1e53e 100644 --- a/KubernetesWorkflow/WorkflowNumberSource.cs +++ b/KubernetesWorkflow/WorkflowNumberSource.cs @@ -4,13 +4,11 @@ namespace KubernetesWorkflow { public class WorkflowNumberSource { - private readonly NumberSource servicePortNumberSource; private readonly NumberSource containerNumberSource; - public WorkflowNumberSource(int workflowNumber, NumberSource servicePortNumberSource, NumberSource containerNumberSource) + public WorkflowNumberSource(int workflowNumber, NumberSource containerNumberSource) { WorkflowNumber = workflowNumber; - this.servicePortNumberSource = servicePortNumberSource; this.containerNumberSource = containerNumberSource; } @@ -20,10 +18,5 @@ namespace KubernetesWorkflow { return containerNumberSource.GetNextNumber(); } - - public int GetServicePort() - { - return servicePortNumberSource.GetNextNumber(); - } } }