docker-event-handler/main.go

105 lines
2.2 KiB
Go

package main
import (
"git.ztn.sh/gwendolyn/docker-event-handler/events"
"git.ztn.sh/gwendolyn/docker-event-handler/handlers"
"context"
"log"
"os"
"strconv"
"time"
"github.com/docker/docker/api/types"
dockerEvents "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
"gopkg.in/ini.v1"
)
type Configuration struct {
handlers []handlers.Handler
}
func handleEvent(dockerClient *client.Client, event dockerEvents.Message, handlers []handlers.Handler) {
e := events.Make(event, dockerClient)
if e == nil {
return
}
log.Printf("%T%+v", e, e)
for _, handler := range handlers {
if handler.Matches(e) {
err := handler.Invoke(e)
if err != nil {
log.Printf("error invoking handler: %v", err)
}
}
}
}
func readConfiguration(path string) (Configuration, error) {
var config Configuration
cfg, err := ini.LoadSources(ini.LoadOptions{
AllowNonUniqueSections: true,
AllowShadows: true,
}, path)
if err != nil {
return config, err
}
for _, section := range cfg.Sections() {
if section.Name() == "DEFAULT" {
continue
}
handler, err := handlers.ReadFromConfig(section)
if err != nil {
return config, err
}
config.handlers = append(config.handlers, handler)
}
return config, nil
}
func main() {
configPath := "/etc/docker-event-handler.conf"
if len(os.Args) > 1 {
if len(os.Args) > 2 {
log.Fatal("too many arguments")
}
configPath = os.Args[1]
}
config, err := readConfiguration(configPath)
if err != nil {
log.Fatal("configuration parsing failed", err)
}
dockerClient, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation())
if err != nil {
log.Fatal("docker connection failed", err)
}
evs, errs := dockerClient.Events(context.TODO(), types.EventsOptions{
Since: strconv.FormatInt(time.Now().Unix(), 10),
Filters: filters.NewArgs(
filters.Arg("type", dockerEvents.ContainerEventType),
filters.Arg("type", dockerEvents.NetworkEventType),
filters.Arg("type", dockerEvents.VolumeEventType),
),
})
for {
select {
case err := <-errs:
log.Fatal("event stream failed", err)
case event := <-evs:
handleEvent(dockerClient, event, config.handlers)
}
}
}