Files
tinyauth/internal/service/docker_service.go
Stavros f0d2da281a feat: header based acls (#337)
* feat: add header decoder

* feat: allow for dash substitute over slash for environments like kubernetes

* feat: use decoded headers in proxy controller

* refactor: simplify decode header to node function

* refactor: use stdlib prefix check in header decoder

* fix: lowercase key and filter before comparing
2025-09-02 19:06:52 +03:00

100 lines
2.4 KiB
Go

package service
import (
"context"
"strings"
"tinyauth/internal/config"
"tinyauth/internal/utils/decoders"
container "github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/rs/zerolog/log"
)
type DockerService struct {
client *client.Client
context context.Context
}
func NewDockerService() *DockerService {
return &DockerService{}
}
func (docker *DockerService) Init() error {
client, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
return err
}
ctx := context.Background()
client.NegotiateAPIVersion(ctx)
docker.client = client
docker.context = ctx
return nil
}
func (docker *DockerService) GetContainers() ([]container.Summary, error) {
containers, err := docker.client.ContainerList(docker.context, container.ListOptions{})
if err != nil {
return nil, err
}
return containers, nil
}
func (docker *DockerService) InspectContainer(containerId string) (container.InspectResponse, error) {
inspect, err := docker.client.ContainerInspect(docker.context, containerId)
if err != nil {
return container.InspectResponse{}, err
}
return inspect, nil
}
func (docker *DockerService) DockerConnected() bool {
_, err := docker.client.Ping(docker.context)
return err == nil
}
func (docker *DockerService) GetLabels(appDomain string) (config.App, error) {
isConnected := docker.DockerConnected()
if !isConnected {
log.Debug().Msg("Docker not connected, returning empty labels")
return config.App{}, nil
}
containers, err := docker.GetContainers()
if err != nil {
return config.App{}, err
}
for _, ctr := range containers {
inspect, err := docker.InspectContainer(ctr.ID)
if err != nil {
log.Warn().Str("id", ctr.ID).Err(err).Msg("Error inspecting container, skipping")
continue
}
labels, err := decoders.DecodeLabels(inspect.Config.Labels)
if err != nil {
log.Warn().Str("id", ctr.ID).Err(err).Msg("Error getting container labels, skipping")
continue
}
for appName, appLabels := range labels.Apps {
if appLabels.Config.Domain == appDomain {
log.Debug().Str("id", inspect.ID).Msg("Found matching container by domain")
return appLabels, nil
}
if strings.TrimPrefix(inspect.Name, "/") == appName {
log.Debug().Str("id", inspect.ID).Msg("Found matching container by app name")
return appLabels, nil
}
}
}
log.Debug().Msg("No matching container found, returning empty labels")
return config.App{}, nil
}