diff --git a/stack_orchestrator/deploy/k8s/cluster_info.py b/stack_orchestrator/deploy/k8s/cluster_info.py index dbf7c907..342dc16c 100644 --- a/stack_orchestrator/deploy/k8s/cluster_info.py +++ b/stack_orchestrator/deploy/k8s/cluster_info.py @@ -300,6 +300,14 @@ class ClusterInfo: result.append(pv) return result + def _any_service_has_host_network(self): + for pod_name in self.parsed_pod_yaml_map: + pod = self.parsed_pod_yaml_map[pod_name] + for svc in pod.get("services", {}).values(): + if svc.get("network_mode") == "host": + return True + return False + # TODO: put things like image pull policy into an object-scope struct def get_deployment(self, image_pull_policy: str = None): containers = [] @@ -362,12 +370,22 @@ class ClusterInfo: for service_name in services: labels[key.replace("{name}", service_name)] = value + use_host_network = self._any_service_has_host_network() + template = client.V1PodTemplateSpec( metadata=client.V1ObjectMeta( annotations=annotations, labels=labels ), - spec=client.V1PodSpec(containers=containers, image_pull_secrets=image_pull_secrets, volumes=volumes), + spec=client.V1PodSpec( + containers=containers, + image_pull_secrets=image_pull_secrets, + volumes=volumes, + host_network=use_host_network or None, + dns_policy=( + "ClusterFirstWithHostNet" if use_host_network else None + ), + ), ) spec = client.V1DeploymentSpec( replicas=1, template=template, selector={ diff --git a/stack_orchestrator/deploy/k8s/helpers.py b/stack_orchestrator/deploy/k8s/helpers.py index 80fb9c6a..4a2b05b4 100644 --- a/stack_orchestrator/deploy/k8s/helpers.py +++ b/stack_orchestrator/deploy/k8s/helpers.py @@ -251,9 +251,36 @@ def _generate_kind_port_mappings_from_services(parsed_pod_files): def _generate_kind_port_mappings(parsed_pod_files): port_definitions = [] - # For now we just map port 80 for the nginx ingress controller we install in kind - port_string = "80" - port_definitions.append(f" - containerPort: {port_string}\n hostPort: {port_string}\n") + seen = set() + # Map port 80 for the ingress controller + for port_string in ["80"]: + port_definitions.append( + f" - containerPort: {port_string}\n hostPort: {port_string}\n" + ) + seen.add((port_string, "TCP")) + # Map ports declared in compose services + for pod in parsed_pod_files: + parsed_pod_file = parsed_pod_files[pod] + if "services" in parsed_pod_file: + for service_name in parsed_pod_file["services"]: + service_obj = parsed_pod_file["services"][service_name] + for port_entry in service_obj.get("ports", []): + port_str = str(port_entry) + protocol = "TCP" + if "/" in port_str: + port_str, proto = port_str.split("/", 1) + protocol = proto.upper() + # Handle host:container port mapping - use container port + if ":" in port_str: + port_str = port_str.split(":")[-1] + port_num = port_str.strip("'\"") + if (port_num, protocol) not in seen: + seen.add((port_num, protocol)) + port_definitions.append( + f" - containerPort: {port_num}\n" + f" hostPort: {port_num}\n" + f" protocol: {protocol}\n" + ) return ( "" if len(port_definitions) == 0 else ( " extraPortMappings:\n"