Files
traefik-etcd-advertiser/generator/traefik.go
2025-01-16 12:22:15 +01:00

84 lines
1.9 KiB
Go

package generator
import (
"fmt"
"log/slog"
"math"
"strconv"
"github.com/kevinmidboe/traefik-etcd-advertiser/client/etcd"
"github.com/kevinmidboe/traefik-etcd-advertiser/converter"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
)
const traefikPrefix = "traefik"
func isKnownGenericType(value interface{}) bool {
switch v := value.(type) {
case string:
return true
case float64:
return true
case bool:
return true
default:
slog.Debug(fmt.Sprintf("found unknown generic %s\n", v))
}
return false
}
func convertToGeneric(value interface{}) string {
switch v := value.(type) {
case string:
return v
case float64:
return fmt.Sprintf("%d", int(math.Floor(v)))
case bool:
return strconv.FormatBool(v)
}
return "unknown type"
}
// recursively walks the JSON object and creates internal
// `etcdPackets` per leaf node, returns list of packets.
func createPacket(item interface{}, parentKey string) []etcd.EtcdPacket {
blocks := []etcd.EtcdPacket{}
switch itemD := item.(type) {
// input is JSON object
case map[string]interface{}:
for key, value := range itemD {
// check for generic value type vs nested object,
// either create block or recursively call obj again
if isKnownGenericType(value) {
blocks = append(blocks, etcd.EtcdPacket{
Key: parentKey + "/" + key,
Value: convertToGeneric(value),
})
} else {
blocks = append(blocks, createPacket(itemD[key], fmt.Sprintf("%s/%s", parentKey, key))...)
}
}
// input is JSON list
case []interface{}:
for i, item := range itemD {
blocks = append(blocks, createPacket(item, parentKey+"/"+strconv.Itoa(i))...)
}
}
return blocks
}
func TraefikToEtcd(config *dynamic.Configuration, packetList *[]etcd.EtcdPacket) {
// always convert to json before converting to etcd
data := converter.TraefikToJSON(config)
// generate list of etcd commands
items := createPacket(data, traefikPrefix)
*packetList = append(*packetList, items...)
}