feat(network-go): add fuzzy container name resolution for firewall connections
continuous-integration/drone/push Build is passing

Implement FindContainerName method on DockerAPI that attempts exact match
first, then falls back to prefix-based matching (e.g., extracting prefix
before dash like "service-" in "service-abc") to replicate the old shell
script's `grep $D"-"` behavior. Update firewall orchestrator to use this
resolution before connecting containers to networks, improving robustness
when container names vary from configured selectors.
This commit is contained in:
gyurix
2026-06-15 14:58:29 +02:00
parent c6ae1748cf
commit aac9b83576
3 changed files with 78 additions and 5 deletions
+53
View File
@@ -5,9 +5,11 @@ import (
"fmt"
"net"
"os/exec"
"strings"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
@@ -26,6 +28,7 @@ type DockerAPI interface {
WaitForContainerRunning(ctx context.Context, containerName string, timeout time.Duration) error
GetContainerPID(ctx context.Context, containerName string) (int, error)
AddRouteInContainer(ctx context.Context, containerName, network, gateway string) error
FindContainerName(ctx context.Context, name, selector string) (string, error)
}
// Client wraps the Docker SDK client
@@ -197,4 +200,54 @@ func (c *Client) AddRouteInContainer(ctx context.Context, containerName, network
return fmt.Errorf("failed to add route in container %s: %w\noutput: %s", containerName, err, string(output))
}
return nil
}
// FindContainerName attempts to find a running container by name or selector.
// First tries the exact name, then tries listing running containers whose name
// starts with the selector prefix (or the name prefix), matching the old shell
// script's grep $D"-" behavior.
func (c *Client) FindContainerName(ctx context.Context, name, selector string) (string, error) {
// First try the exact name
cont, err := c.cli.ContainerInspect(ctx, name)
if err == nil && cont.State != nil && cont.State.Running {
return name, nil
}
// Try exact selector
if selector != "" && selector != name {
cont, err := c.cli.ContainerInspect(ctx, selector)
if err == nil && cont.State != nil && cont.State.Running {
return selector, nil
}
}
// Try prefix matching with selector (old shell script behavior: grep $D"-")
candidates := []string{name, selector}
for _, candidate := range candidates {
if candidate == "" {
continue
}
// Extract prefix before first dash if present
prefix := candidate
if strings.Contains(candidate, "-") {
prefix = candidate[:strings.Index(candidate, "-")]
}
containers, err := c.cli.ContainerList(ctx, container.ListOptions{})
if err != nil {
continue
}
for _, container := range containers {
// Remove leading / from container names
for _, cName := range container.Names {
cName = strings.TrimPrefix(cName, "/")
if strings.HasPrefix(cName, prefix+"-") && container.State == "running" {
return cName, nil
}
}
}
}
return "", fmt.Errorf("no running container found matching name=%q selector=%q", name, selector)
}